public static Mesh LoadMesh(Device device, string file, ref Material[] meshMaterials, ref Texture[] meshTextures){ ExtendedMaterial[] mtrl; Mesh tempMesh = Mesh.FromFile(file, MeshFlags.Managed, device, out mtrl); if ((mtrl != null) && (mtrl.Length > 0)){ meshMaterials = new Material[mtrl.Length];meshTextures = new Texture[mtrl.Length]; for (int i = 0; i < mtrl.Length; i++){ meshMaterials[ i ] = mtrl[ i ].Material3D; if ((mtrl[ i ].TextureFilename != null) && (mtrl[ i ].TextureFilename.Length > 0)){ meshTextures[ i ] = TextureLoader.FromFile(device, @"..\..\" + mtrl[ i ].TextureFilename);} } } return tempMesh;} |
using (VertexBuffer vb = Mesh.VertexBuffer)
float objectRadius = 0.0f;
Vector3 objectCenter = new Vector3();
{
GraphicsStream vertexData = vb.Lock(0, 0, LockFlags.None);
objectRadius = Geometry.ComputeBoundingSphere(vertexData,
mesh.NumberVertices,
mesh.VertexFormat,
out objectCenter);
vb.Unlock();
}
also what are you looking for in .fx file. are you looking for an example .fx file or code to implement them in program?
well here is a simple .fx file written in HLSL it is very close to C.
//Simple.fx
//Written in HLSL
// The world view and projection matrices
float4x4 WorldViewProj : WORLDVIEWPROJECTION;
sampler TextureSampler;
// Transform our coordinates into world space
void Transform(
in float4 inputPosition : POSITION,
in float2 inputTexCoord : TEXCOORD0,
out float4 outputPosition : POSITION,
out float2 outputTexCoord : TEXCOORD0
)
{
// Transform our position
outputPosition = mul(inputPosition, WorldViewProj);
// Set our texture coordinates
outputTexCoord = inputTexCoord;
}
void TextureColor(
in float2 textureCoords : TEXCOORD0,
out float4 diffuseColor : COLOR0)
{
// Get the texture color
diffuseColor = tex2D(TextureSampler, textureCoords);
};
technique TransformTexture
{
pass P0
{
// shaders
VertexShader = compile vs_1_1 Transform();
PixelShader = compile ps_1_1 TextureColor();
}
}
This code is taken directly from Tom Miller's book. This simple effect file will render a mesh using the programmable pipeline. Basically you pass in the position of the vertices and texture coords and this will transform them to world space and color/texture them. This file doesn't do anything fancy but effect files are where you can do some pretty cool things. Ok now to a little bit of C# to render the mesh with this code.
//Setup code for effect
// Create our effect
Private Effect effect = null;
effect = Effect.FromFile(device, @"simple.fx", null, ShaderFlags.None, null);
effect.Technique = "TransformTexture";
//render method for mesh
//1. setup world matrix
//2. pass effect file worldViewProj for position calc
//3. begin effect pass
//4. render mesh
//5. end effect pass
private void render(){
worldMatrix = Matrix.Translation(0f,0f,0f);
Matrix worldViewProj = worldMatrix * viewMatrix * projMatrix;
effect.SetValue("WorldViewProj", worldViewProj);
int numPasses = effect.Begin(0);
for (int iPass = 0; iPass < numPasses; iPass++)
{
effect.Pass(iPass);
for (int i = 0; i < meshMaterials.Length; i++)
{
device.SetTexture(0, meshTextures[ i ]);
mesh.DrawSubset(i);
}
}
effect.End();
}
That is some quick code for rendering the mesh with the effect file. First you set up the effect and technique. Then use it to render. If you have any questions please don't hesitate to ask. I am not very good at teaching, sorry.
public void Painthome(Start start,Device device,double appTime, float elapsedTime) { bool beginSceneCalled = false;device.Clear(ClearFlags.ZBuffer | ClearFlags.Target, 0x002D32AA, 1.0f,0); try{ device.BeginScene(); beginSceneCalled = true;start.backgroundSprite.Begin(SpriteFlags.AlphaBlend); start.backgroundTextureSize = new System.Drawing.Rectangle(0,0,800, 600);start.backgroundSprite.Draw(start.backgroundSpriteTexture,start.backgroundTextureSize, new Vector3(0,0,0),new Vector3(0,0,1),System.Drawing.Color.White);start.backgroundSprite.End(); start.PmeshZ = 60.0F; start.LeftnRight = -15.0F; start.pUpnDown = -5.0F; start.effect.SetValue("worldViewProjection", start.camera.WorldMatrix * start.viewMatrix * start.camera.ProjectionMatrix);//the effects file Im using is the SampleUI effects file edited to use no pixel shader rendering start.effect.SetValue("worldMatrix", start.camera.WorldMatrix); start.effect.Technique = "RenderSceneNoPixelShader"; int passes = start.effect.Begin(0);Mesh localMesh = start.mesh.LocalMesh; for (int pass = 0; pass < passes; pass++){ start.effect.BeginPass(pass); for(int i = 0; i < start.mesh.NumberMaterials; i++){ start.effect.SetValue("sceneTexture", start.mesh.GetTexture(i)); start.effect.CommitChanges(); start.camera.FrameMove(elapsedTime);//not sure if this is in the right spot but it lets the user spin the mesh start.viewMatrix.AffineTransformation(1, new Vector3(1,8,0),Microsoft.DirectX.Quaternion.RotationYawPitchRoll(start.y,start.p,start.r),new Vector3(start.LeftnRight,start.pUpnDown,start.PmeshZ));//using this to place the mesh in a set location} localMesh.DrawSubset(i); } start.effect.EndPass(); } start.effect.End(); start.HomeDialog.OnRender(elapsedTime); } finally{ if (beginSceneCalled)device.EndScene(); } } |
as you can see here im not rotating anything just allowing mouse input to spin the mesh around, some spin good(not as good as in the mesh viewer) and some spin really bad, like the whole mesh moves from left to right front to back. sorry I seem to be having a problem explaining this.
it was a mesh problem, something to do with the texturing of the meshes, thanks again for the help, but I dont seem to beable to get the lights working right if I set then using device.Lights[0] ect nothing happends any ideas why this might happen?
public void Painthome(Start start,Device device,double appTime, float elapsedTime) { bool beginSceneCalled = false;device.Clear(ClearFlags.ZBuffer | ClearFlags.Target, 0x002D32AA, 1.0f,0); try{ device.Lights[0].Type = LightType.Directional; device.Lights[0].Diffuse = System.Drawing.Color.White; device.Lights[0].Direction = new Vector3()device.Lights[0].Enabled = true; //lightsdevice.BeginScene(); beginSceneCalled = true;start.backgroundSprite.Begin(SpriteFlags.AlphaBlend); start.backgroundTextureSize = new System.Drawing.Rectangle(0,0,800, 600);start.backgroundSprite.Draw(start.backgroundSpriteTexture,start.backgroundTextureSize, new Vector3(0,0,0),new Vector3(0,0,1),System.Drawing.Color.White);start.backgroundSprite.End(); start.PmeshZ = 60.0F; start.LeftnRight = -15.0F; start.pUpnDown = -5.0F; start.effect.SetValue("worldViewProjection", start.camera.WorldMatrix * start.viewMatrix * start.camera.ProjectionMatrix);//the effects file Im using is the SampleUI effects file edited to use no pixel shader rendering start.effect.SetValue("worldMatrix", start.camera.WorldMatrix); start.effect.Technique = "RenderSceneNoPixelShader"; int passes = start.effect.Begin(0);Mesh localMesh = start.mesh.LocalMesh; for (int pass = 0; pass < passes; pass++){ start.effect.BeginPass(pass); for(int i = 0; i < start.mesh.NumberMaterials; i++){ start.effect.SetValue("sceneTexture", start.mesh.GetTexture(i)); start.effect.CommitChanges(); start.camera.FrameMove(elapsedTime);//not sure if this is in the right spot but it lets the user spin the mesh start.viewMatrix.AffineTransformation(1, new Vector3(1,8,0),Microsoft.DirectX.Quaternion.RotationYawPitchRoll(start.y,start.p,start.r),new Vector3(start.LeftnRight,start.pUpnDown,start.PmeshZ));//using this to place the mesh in a set location} localMesh.DrawSubset(i); } start.effect.EndPass(); } start.effect.End(); start.HomeDialog.OnRender(elapsedTime); } finally{ if (beginSceneCalled)device.EndScene(); } } |
in the debugger Im looking for the lights value but it says cant obtain value
and unless we have another mesh issue the colors of the meshes are not comming out right.
those are my first two guesses and these are easy fixes.