2012-05-07 17 views
2

私はViewport3D(CurViewport3D)をオフスクリーンで作成し、それを1つのプレーンのみで(テスト目的で)作成します。wpf Viewport3DのRenderTargetBitmap(オフスクリーン)

経由でRenderTargetBitmapとBitmapEncoderこのビューポートのコンテンツのMemoryStream(jpgとして)が作成されます。私はこのライブラリを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サーバーで実行する方法を知っていますか?

答えて

1

答えは非常にシンプルです:WPF 3DレンダリングはSession 0 Isolationで動作しません.Windows 2008サーバー以上の非対話ユーザー(またはVista /クライアントでは7人)に適用されます。これらのすべてが0とは異なるセッションでWPF図面をホストしているサーバー(リモートユーザーさえも)にログオンしているユーザーを必要とするため、 I did not find any real solution to the same problemです。 本当に徹底的な解決策として、私はOpenGLを使って同じことを実現しました。OpenGLは純粋なソフトウェアでレンダリングできるので、セッション0の影響を受けません。

+0

あなたが絶対に正しいと思われます。しかし、OpenGLを使ってWPFビューポートをレンダリングする方法を教えてください。なぜそれを徹底的な解決策と名づけますか? – manton

+0

あなたは完全にWPFを放棄していますので、驚いています。ちょうどOpenGL(私はSharpGLを使用しています)を使用してシーンをビットマップでレンダリングします。私のscheneは非常にシンプルで、3次元のマルチハイトの円グラフでした.z座標を逆転するだけですべてのメッシュを再利用することができました。プロセスは複雑ではありませんが、ここでは難しいでしょう。 –

-1

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

これが当てはまらない場合は、実行しているメモリストリームと関係があります。メモリストリームを使用する必要がある理由は100%ありますか?それがない場合は解決策を試しても問題が解決するかどうか確認してください。

関連する問題