游戏开发论坛

 找回密码
 立即注册
搜索
查看: 1704|回复: 1

关于在 F# 中使用 Direct3D

[复制链接]

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
发表于 2008-9-16 16:18:00 | 显示全部楼层 |阅读模式
可能是我的 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 ----

362

主题

3023

帖子

3553

积分

论坛元老

Rank: 8Rank: 8

积分
3553
 楼主| 发表于 2008-9-27 22:39:00 | 显示全部楼层

Re:关于在 F# 中使用 Direct3D

以上代码我已经成功运行了。而且aug2005版本等也可以。
很简单,点“继续”就OK了。

不过,关于 Microsoft.FSharp.Matrix 命名空间中的 mul 的兼容性,很有问题。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2026-1-21 05:59

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表