2

Viewport3D (CurViewport3D) オフスクリーンを作成し、(テスト目的で) 1 つの平面だけで埋めます。

RenderTargetBitmap と BitmapEncoder を介して、このビューポートのコンテンツ (jpg として) の MemoryStream が作成されます。Web サーバーでこのライブラリを使用して、Web サイトに表示する画像を作成したいので、機能全体をライブラリ (dll) に入れます。

以下のコードは基本的なものに縮小されていますが、機能しています。

using System;
using System.Collections.Generic;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;
using System.Windows.Shapes;
using System.Windows.Controls;
using System.Windows.Threading;

namespace RenderTargetImage_Test
{
    public class RenderTargetImage01
    {
        public System.IO.MemoryStream stream = new System.IO.MemoryStream();
        Int32 width = 100;
        Int32 height = 100;
        Viewport3D CurViewport3D;

        public RenderTargetImage01()
        {
            CurViewport3D = new Viewport3D();
            Model3DGroup myModel3DGroup = new Model3DGroup();
            ModelVisual3D myModelVisual3D = new ModelVisual3D(); 

            PerspectiveCamera myPCamera = new PerspectiveCamera();
            myPCamera.Position = new Point3D(3500, 1500, -5000);
            myPCamera.LookDirection = new Vector3D(-0.5, 0, 1);
            myPCamera.FieldOfView = 70;
            CurViewport3D.Camera = myPCamera;

            AmbientLight myAmbientLight = new AmbientLight();
            myAmbientLight.Color = Colors.White;
            myModel3DGroup.Children.Add(myAmbientLight);

            MeshGeometry3D meshS2 = new MeshGeometry3D();
            GeometryModel3D modelS2 = new GeometryModel3D();

            meshS2.Positions.Add(new Point3D(500, 500, -500));
            meshS2.Positions.Add(new Point3D(500, 3000, -500));
            meshS2.Positions.Add(new Point3D(3000, 500, -500));
            meshS2.Positions.Add(new Point3D(3000, 3000, -500));
            meshS2.TriangleIndices.Add(0);
            meshS2.TriangleIndices.Add(1);
            meshS2.TriangleIndices.Add(2);
            meshS2.TriangleIndices.Add(3);
            meshS2.TriangleIndices.Add(2);
            meshS2.TriangleIndices.Add(1);
            meshS2.Normals.Add(new Vector3D(0, 0, 1));
            meshS2.Normals.Add(new Vector3D(0, 0, 1));
            meshS2.Normals.Add(new Vector3D(0, 0, 1));
            meshS2.Normals.Add(new Vector3D(0, 0, 1));
            meshS2.Normals.Add(new Vector3D(0, 0, 1));
            meshS2.Normals.Add(new Vector3D(0, 0, 1));
            meshS2.TextureCoordinates.Add(new System.Windows.Point(0, 0));
            meshS2.TextureCoordinates.Add(new System.Windows.Point(1, 0));
            meshS2.TextureCoordinates.Add(new System.Windows.Point(0, 1));
            meshS2.TextureCoordinates.Add(new System.Windows.Point(1, 1));

            modelS2.Geometry = meshS2;
            DiffuseMaterial DiffMS2 = new DiffuseMaterial(System.Windows.Media.Brushes.Red);
            modelS2.Material = DiffMS2;
            myModel3DGroup.Children.Add(modelS2);
            myModelVisual3D.Content = myModel3DGroup;
            CurViewport3D.Children.Add(myModelVisual3D);

            // render
            RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap(width, height, 96, 96, PixelFormats.Pbgra32);
            CurViewport3D.Width = width;
            CurViewport3D.Height = height;
            CurViewport3D.Measure(new System.Windows.Size(width, height));
            CurViewport3D.Arrange(new Rect(0, 0, width, height));
            CurViewport3D.Dispatcher.Invoke(((Action)(() => renderTargetBitmap.Render(CurViewport3D))), DispatcherPriority.Render);
            BitmapEncoder bitmapEncoder = new PngBitmapEncoder();
            bitmapEncoder.Frames.Add(BitmapFrame.Create(renderTargetBitmap));
            bitmapEncoder.Save(stream);
        }
    }
}

ここにウェブサイトのコードがあります:

<body>
    <form id="form1" runat="server">
    <div>
    </div>
    </form>
</body>

および背後にあるコード:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.IO;
using System.Windows.Shapes;

using System.Windows.Media;
using System.Windows.Media.Imaging;

using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;

using RenderTargetImage_Test;

public partial class Default2 : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        RenderTargetImage01 rti = new RenderTargetImage01();

        rti.stream.WriteTo(Response.OutputStream);
        Response.ContentType = "image/png";
        Response.Flush();
        Response.End();
    }
}

とても簡単!

問題: ローカルではすべて正常に動作します。ブラウザに画像が表示されます - 完璧です。Web サーバー (Microsoft Server 2008) で実行しようとすると、ブラウザーに表示される画像は空で、コンテンツがありません。エラーなし。

Webサーバーで実行する方法を知っている人はいますか?

4

3 に答える 3

1

答えは非常に簡単です。WPF 3D レンダリングは、Windows 2008 サーバー以降 (またはクライアントの Vista/Seven) の非対話型ユーザーに適用される セッション 0 分離では機能しません。同じ問題に対する実際の解決策は見つかりませんでした。これらはすべて、 0 以外のセッションで WPF 図面をホストしているサーバーにログオンしているユーザー (リモート ユーザーであっても) が必要だからです。したがって、非常に抜本的な解決策として、OpenGL を使用して同じものをレンダリングしました。OpenGL は純粋なソフトウェアの方法でレンダリングできるため、セッション 0 の影響を受けず、魅力的に機能します。

于 2013-03-26T10:28:14.020 に答える
-1

レンダリング中にビューポートがオフスクリーンになるのは問題のようです。これは、ビューポートの結果が実際に画面にレンダリングされることはないと私は信じています。現在はローカルで動作するため、問題はサーバーのグラフィック ハードウェアにある可能性があります。ローカルには、呼び出されたものすべてをレンダリングするハードウェアがあるかもしれませんが、サーバーはおそらくソフトウェアを介してすべてをレンダリングしています。ソフトウェアは、タイミングとリソースを節約するために、表示できないものをすべて無効にします。グラフィックス ハードウェアは引き続きすべてをレンダリングし、表示可能になるまでバッファに格納します。

そうでない場合は、実行しているメモリ ストリームに関係していると言わざるを得ません。メモリ ストリームを使用しなければならない 100% の理由はありますか? そうでない場合は、それなしで解決策を試して、問題が解決するかどうかを確認してください。

于 2012-09-27T08:01:09.407 に答える