我在屏幕外創建一個Viewport3D(CurViewport3D)並僅用一個平面填充(用於測試目的)。wpf在Web服務器上的Viewport3D的RenderTargetBitmap(離屏)
通過RenderTargetBitmap和BitmapEncoder創建此視口內容的MemoryStream(如jpg)。整個功能都放在一個庫(dll)中,因爲我想在Web服務器上使用這個庫來創建一個圖像在網站上顯示。
下面的代碼簡化爲基礎,但它工作。
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)上運行它,瀏覽器中顯示的圖像是空的,沒有內容。沒有錯誤。
有誰知道如何讓它在網絡服務器上運行?
看來你是完全正確的。但是,你能告訴我如何使用OpenGL呈現WPF視口嗎?你爲什麼把它命名爲一個徹底的解決方案? – manton
因爲你完全放棄了WPF而鬱鬱蔥蔥,只是使用OpenGL(我使用SharpGL)來渲染你的場景。我的方案非常簡單 - 一個三維多高餅圖 - 我能夠通過反轉z-coord來重用所有網格。過程並不複雜,但很難,也可能是OT。 –