|
|
可能是我的 F# 比较旧把。
提示我,“Direct3D.dll, DllMain中不能。。。”
请问有谁知道?
F#不是过程式,写d3d会很方便的。
找到了一个例子:
---- Matrices.fs ----
open System
open System.Drawing
open System.Windows.Forms
open Microsoft.DirectX
open Microsoft.DirectX.Direct3D
open Idioms
open Microsoft.FSharp.Compatibility.CompatArray
open Microsoft.FSharp.MLLib.Int32
open Microsoft.FSharp.MLLib.Float
type 'a typ = { result: System.Type }
let typeof () : typ<'a> =
let res =
// This is MSIL 2.0 assembly language, which means you need to have
// the .NET 2.0 (beta or final) runtime installed to compile and
// run this sample.
(# "ldtoken !0
call class [mscorlib]System.Type
[mscorlib]System.Type::GetTypeFromHandle
(valuetype [mscorlib]System.RuntimeTypeHandle)"
: System.Type ) in
{ result = res }
type MyFormData = {
mutable device : Device; // mutable because it starts out NULL and gets filled in later.
mutable vertexBuffer : VertexBuffer;
mutable pause : bool
}
let _ =
// Create our form's instance data:
let md = { device = null; vertexBuffer = null; pause = false } in
// Create the Render function. This was a method in C#, but we can't
// create methods in F#, so we use a function instead. The md argument
// acts a lot like a "this" pointer.
let SetupMatrices md =
// For our world matrix, we will just rotate the object about the y-axis.
// Set up the rotation matrix to generate 1 full rotation (2*PI radians)
// every 1000 ms. To avoid the loss of precision inherent in very high
// floating point numbers, the system time is modulated by the rotation
// period before conversion to a radian angle.
// F# distinguishes between int, float, and float32. int and float are
// the native F# types, float32 is the CLR floating point type.
let iTime = Environment.TickCount mod 1000 in
let PI = 3.14159 in
let QuarterPI = PI /. 4. in
let fAngle : Single = to_float32(to_float(iTime) *. PI /. 500.0) in
md.device.Transform.World <- Matrix.RotationY( fAngle );
// Set up our view matrix. A view matrix can be defined given an eye point,
// a point to lookat, and a direction for which way is up. Here, we set the
// eye five units back along the z-axis and up three units, look at the
// origin, and define "up" to be in the y-direction.
md.device.Transform.View <- Matrix.LookAtLH( new Vector3( 0.0f, 3.0f, -5.0f ),
new Vector3( 0.0f, 0.0f, 0.0f ), new Vector3( 0.0f, 1.0f, 0.0f ) );
// For the projection matrix, we set up a perspective transform (which
// transforms geometry from 3D view space to 2D viewport space, with
// a perspective divide making objects smaller in the distance). To build
// a perpsective transform, we need the field of view (1/4 pi is common),
// the aspect ratio, and the near and far clipping planes (which define at
// what distances geometry should be no longer be rendered).
md.device.Transform.Projection <- Matrix.PerspectiveFovLH( to_float32(QuarterPI),
1.0f, 1.0f, 100.0f );
in
let Render md =
if md.device != null && md.pause = false then
begin
md.device.Clear(ClearFlags.Target, System.Drawing.Color.Blue, 1.0f, 0);
md.device.BeginScene();
SetupMatrices md;
md.device.SetStreamSource( 0, md.vertexBuffer, 0);
md.device.VertexFormat <- CustomVertex.PositionColored.Format;
md.device.DrawPrimitives(PrimitiveType.TriangleList, 0, 1);
md.device.EndScene();
md.device.Present()
end
in
// Create an instance of a form with overidden OnPaint and OnKeyPress methods.
// Note that the "md" record is captured from the enclosing environment. This
// is how we get our instance variables into our form.
let form = {
new Form() as base
with OnPaint(e) = Render md
and OnKeyPress(e) =
if e.KeyChar = char_of_int(EnumToInt(Keys.Escape)) then
base.Close()
and OnResize(e) =
md.pause <- (base.WindowState = FormWindowState.Minimized) || base.Visible == false
} in
let presentParams = new PresentParameters() in
presentParams.Windowed <- true;
presentParams.SwapEffect <- SwapEffect.Discard;
// Two tricky things here to exactly match the Device constructor:
// 1) form has to be explicitly upcast to a Control
// 2) presentParams has to be made into an array of one element
md.device <- new Device(0, DeviceType.Hardware, (form :> Control),
CreateFlags.SoftwareVertexProcessing, [|presentParams|]);
md.vertexBuffer <- new VertexBuffer(
(typeof() : typ<CustomVertex.PositionColored>).result,
3, md.device, Usage.None, CustomVertex.PositionColored.Format,
Pool.Default);
let OnCreateVertexBuffer (sender : obj) (e : EventArgs) =
let vb = sender :?> VertexBuffer in
let stm = vb.Lock(0, 0, LockFlags.None) in
let verts : CustomVertex.PositionColored[] = zero_create 3 in
// F# has no l-values, so we have to create new verts and copy them into the array,
// rather than updating the verts that are already in the array.
set verts 0 (new CustomVertex.PositionColored(
-1.0f, -1.0f, 0.f, System.Drawing.Color.DarkGoldenrod.ToArgb()));
set verts 1 (new CustomVertex.PositionColored(
1.0f, -1.0f, 0.f, System.Drawing.Color.MediumOrchid.ToArgb()));
set verts 2 (new CustomVertex.PositionColored(
0.0f, 1.0f, 0.f, System.Drawing.Color.Cornsilk.ToArgb()));
// box and unbox to convert a [] array into a System.Array
stm.Write((unbox (box verts)) : System.Array);
vb.Unlock()
and OnDeviceReset (sender : obj) (e : EventArgs) =
let dev = sender :?> Device in
// Turn off culling, so we see the front and back of the triangle
dev.RenderState.CullMode <- Cull.None;
// Turn off D3D lighting, since we are providing our own vertex colors
dev.RenderState.Lighting <- false;
in
// add_Created is the canonical name of the function that adds event handlers
// to the "Created" event
md.vertexBuffer.add_Created(new EventHandler(OnCreateVertexBuffer));
md.device.add_DeviceReset(new EventHandler(OnDeviceReset));
// Must cast types to match exactly.
OnCreateVertexBuffer (md.vertexBuffer :> obj) (null : EventArgs);
OnDeviceReset (md.device :> obj) (null : EventArgs);
form.Text <- "F# Direct3D Tutorial 3 - Matrices";
form.ClientSize <- new Size(400, 300);
// Setting ClientSize resized the form, which set pause to true
// because the form is still hidden. So set pause to false here.
md.pause <- false;
form.Visible <- true;
while form.Created do
Render md;
Application.DoEvents();
done
---- end of Matrices.fs ----
|
|