Salut tout le monde,
Ce programme montre comment tracer un vecteur, et comment tracer un plan qui lui est perpendiculaire (le petit carré)
Pour y arriver, j'utilise les coordonnées polaires (longitude et latitude) ainsi que la multiplication par les matrices de rotation
Le code source est simple et bien structuré (selon moi ;)
j'espère que vous aller apprecier
Je tiens à remercier mon père qui a donné généreusement de son temps pour le débogage de cette application qui semblait vouée à l'échec :p
Source / Exemple :
using System;
using System.Drawing;
using Microsoft.DirectX;
using Microsoft.DirectX.Direct3D;
namespace tube3d
{
public class directxGestion
{
//device pour l'affichage
private Device device = null;
//handle sur la surface d'affichage
private IntPtr handle;
//buffer de vecteur pour les axes x, y, z
private VertexBuffer axes = null;
//buffer de vecteur pour le carré
private VertexBuffer square = null;
//buffer de vecteur pour le vecteur
private VertexBuffer vecteur = null;
public int x1=0, y1=0, z1=0;
public int x2=0, y2=0, z2=4;
public int cameraX = 2, cameraY = 2, cameraZ = 5;
private double latitude = Math.PI/2, longitude = 0;
private float[,] squarePoints = new float[4,3] {{-2,2,0},{2,2,0},{-2,-2,0},{2,-2,0}};
#region CustomVertex
const VertexFormats customVertexFormat = VertexFormats.Position | VertexFormats.Diffuse | VertexFormats.Texture1;
private struct CustomVertex
{
public float X;
public float Y;
public float Z;
public int color;
public float tu;
public float tv;
}
private CustomVertex CreateVertex(float x, float y, float z, float tu, float tv, int color)
{
CustomVertex custVertex = new CustomVertex();
custVertex.X = x; custVertex.Y = y; custVertex.Z = z;
custVertex.color = color;
custVertex.tu = tu; custVertex.tv = tv;
return custVertex;
}
#endregion
public directxGestion(IntPtr handle)
{
this.handle = handle;
}
#region InitDevice
public bool InitDevice(bool fullscreen)
{
DisplayMode DispMode = Manager.Adapters[Manager.Adapters.Default.Adapter].CurrentDisplayMode;
PresentParameters presentParams = new PresentParameters();
if(fullscreen) {presentParams.BackBufferFormat = DispMode.Format; presentParams.BackBufferWidth = DispMode.Width; presentParams.BackBufferHeight = DispMode.Height;}
//on veut que notre device supporte la profondeur
presentParams.AutoDepthStencilFormat = DepthFormat.D16;
presentParams.EnableAutoDepthStencil = true;
//mode fenetre
if(!fullscreen) presentParams.Windowed = true;
//mode de switchage de buffer
presentParams.SwapEffect = SwapEffect.Discard;
//attendre la synchronisation avec l'ecran (VSync)
//utiliser PresentInterval.Immediate pour des vitesses rapides
presentParams.PresentationInterval = PresentInterval.One;
try
{
//on crée le device selon les paramètres de présentation si-dessus
if(fullscreen) device = new Device(Manager.Adapters.Default.Adapter, DeviceType.Hardware, this.handle, CreateFlags.SoftwareVertexProcessing, presentParams);
else device = new Device(Manager.Adapters.Default.Adapter, DeviceType.Hardware, this.handle, CreateFlags.SoftwareVertexProcessing, presentParams);
//on lui associe notre format de vecteur spécial
device.VertexFormat = customVertexFormat;
//on active le z-buffer
device.RenderState.ZBufferEnable = false;
//pas de culling
device.RenderState.CullMode = Cull.None;
//mode de remplissage des polygones (ici solide)
device.RenderState.FillMode = FillMode.Solid;
//pas de lumière
device.RenderState.Lighting = false;
//activation de l'alpha blending
device.RenderState.AlphaBlendEnable = true;
device.RenderState.DestinationBlend = Blend.DestinationAlpha;
device.RenderState.SourceBlend = Blend.SourceAlpha;
//on définit le mode de projection
device.Transform.Projection = Matrix.OrthoLH(20,20,100,-100);
//on positionne la caméra
device.Transform.View = Matrix.LookAtLH(new Vector3(-cameraX,-cameraY,-cameraZ), new Vector3(0,0,0), new Vector3(0,1,0));
}
catch
{
return false;
}
return true;
}
#endregion
#region Initialisation des vertexBuffer
#region InitBuffers
public void InitBuffers()
{
//on crée les buffers qui va contenir nos vecteurs
axes = new VertexBuffer(typeof(CustomVertex), 6, device, Usage.WriteOnly, customVertexFormat, Pool.Default);
square = new VertexBuffer(typeof(CustomVertex), 4, device, Usage.WriteOnly, customVertexFormat, Pool.Default);
vecteur = new VertexBuffer(typeof(CustomVertex), 2, device, Usage.WriteOnly, customVertexFormat, Pool.Default);
//on associe à une fonction, la création de notre buffer
//au cas qu'il soit perdu
axes.Created += new EventHandler(this.CreateAxes);
square.Created += new EventHandler(this.CreateSquare);
vecteur.Created += new EventHandler(this.CreateVector);
//on force la création du buffer
CreateAxes(axes, null);
CreateSquare(square, null);
CreateVector(vecteur, null);
}
#endregion
#region creation des 3 axes
private void CreateAxes(object sender, EventArgs e)
{
CustomVertex[] verts = new CustomVertex[6];
//axe des x
verts[0] = CreateVertex(0,0,0,0,0, Color.FromArgb(100, Color.LightBlue).ToArgb());
verts[1] = CreateVertex(10,0,0,0,0, Color.FromArgb(100, Color.LightBlue).ToArgb());
//axe des y
verts[2] = CreateVertex(0,0,0,0,0, Color.FromArgb(100, Color.LightGreen).ToArgb());
verts[3] = CreateVertex(0,10,0,0,0, Color.FromArgb(100, Color.LightGreen).ToArgb());
//axe des z
verts[4] = CreateVertex(0,0,0,0,0, Color.FromArgb(100, Color.Red).ToArgb());
verts[5] = CreateVertex(0,0,20,0,0, Color.FromArgb(100, Color.Red).ToArgb());
axes.SetData(verts, 0, LockFlags.None);
}
#endregion
#region creation du carré
private void CreateSquare(object sender, EventArgs e)
{
CustomVertex[] verts = new CustomVertex[4];
float x=0, y=0, z=0;
float x1=0, y1=0, z1=0;
Matrix rotX = Matrix.RotationX((float)(latitude-Math.PI/2));
Matrix rotY = Matrix.RotationY((float)longitude);
for(int i=0; i<4; i++)
{
x1 = squarePoints[i,0] * rotX.M11 + squarePoints[i,1] * rotX.M21 + squarePoints[i,2] * rotX.M31;
y1 = squarePoints[i,0] * rotX.M12 + squarePoints[i,1] * rotX.M22 + squarePoints[i,2] * rotX.M32;
z1 = squarePoints[i,0] * rotX.M13 + squarePoints[i,1] * rotX.M23 + squarePoints[i,2] * rotX.M33;
x = x1 * rotY.M11 + y1 * rotY.M21 + z1 * rotY.M31;
y = x1 * rotY.M12 + y1 * rotY.M22 + z1 * rotY.M32;
z = x1 * rotY.M13 + y1 * rotY.M23 + z1 * rotY.M33;
x+=this.x1; y+=this.y1; z+=this.z1;
verts[i] = CreateVertex(x,y,z,0,0, Color.FromArgb(150, Color.White).ToArgb());
}
square.SetData(verts, 0, LockFlags.None);
}
#endregion
#region creation du vecteur
private void CreateVector(object sender, EventArgs e)
{
CustomVertex[] verts = new CustomVertex[2];
verts[0] = CreateVertex(x1,y1,z1,0,0, Color.FromArgb(255, Color.Yellow).ToArgb());
verts[1] = CreateVertex(x2,y2,z2,0,0, Color.FromArgb(255, Color.Yellow).ToArgb());
vecteur.SetData(verts, 0, LockFlags.None);
}
#endregion
#endregion
#region Render
public void Render()
{
if(device==null) return;
//on efface l'écran et le z-buffer
device.Clear(ClearFlags.Target|ClearFlags.ZBuffer, Color.Black, 1.0f, 0);
//on commence la scène
device.BeginScene();
//-----------------------------------------------------
device.SetStreamSource(0, axes, 0);
device.DrawPrimitives(PrimitiveType.LineList, 0, 3);
//-----------------------------------------------------
//this.RotationMatrices((int)(this.latitude*180/Math.PI), (int)(this.longitude*180/Math.PI), 0);
device.SetStreamSource(0, square, 0);
device.DrawPrimitives(PrimitiveType.TriangleStrip, 0, 2);
//device.Transform.World = Matrix.Identity;
//-----------------------------------------------------
device.SetStreamSource(0, vecteur, 0);
device.DrawPrimitives(PrimitiveType.LineList, 0, 1);
//on termine le dessin
device.EndScene();
//on l'affiche à l'écran
try{device.Present();}
catch{}
using(Graphics g = Graphics.FromHwnd(this.handle))
{
string str = string.Format("latitude :\t\t{0} degré(s)\nlongitude :\t{1} degré(s)", Math.Round(latitude*180/Math.PI, 0), Math.Round(longitude*180/Math.PI, 0));
g.DrawString(str, new System.Drawing.Font(FontFamily.GenericSansSerif, 12), new SolidBrush(Color.White), new Point(0,0));
}
}
#endregion
public void Invalidate()
{
int x = x2 - x1; int y = y2 - y1; int z = z2 - z1;
this.latitude = Math.Atan2(Math.Sqrt(x*x+z*z), y);
this.longitude = Math.Atan2(x, z);
this.CreateVector(null, null);
this.CreateSquare(null, null);
}
public void SetCamera()
{
device.Transform.View = Matrix.LookAtLH(new Vector3(-cameraX,-cameraY,-cameraZ), new Vector3(0,0,0), new Vector3(0,1,0));
}
}
}
Conclusion :
vous devez avoir DirectX 9.0c
les DLL pour le managed DirectX sont inclus
si vous rencontrez des problèmes, faites moi signe.
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.