编辑 1:
显然,我已经开始以不正确的方式在 WPF 环境中实现 3D 渲染。Ofc 在下面有我的问题的解决方案,但我建议阅读 Sheridan 答案的更新并使用他的建议来实现这一点。它不仅安全,而且性能更好。虽然理解起来有点复杂,但是一旦理解了,就可以开始在WPF中渲染多个3D应用了。感谢您的帮助谢里登!
问题 ;
我是 WPF 的新手,我想用 WPF 设计一个连续的渲染(比如在游戏应用程序中)。我正在使用多线程来提供更好的 UI 控件(开始/停止按钮 fe)。或者,由于使用无限循环来渲染 3D 世界,事件可能会被处理。
但是,我的问题是,在运行程序时,我得到一个Invalid operation was unhandled
错误。问题是有一个对象是主线程的属性,因此新线程可能无法访问它。
从 XAML 文件,
<Grid>
<!-- ui controls omitted ... -->
<Viewport3D Name="myViewport" ClipToBounds="True">
<!-- all inits, camera, pos, ... -->
</Viewport3D>
</Grid>
在主班;
/// <summary>this method is done to render the 3D app in other thread.</summary>
private void Runtime(Viewport3D vp) {
System.Diagnostics.Debug.WriteLine("runtime ");
Render3D r3d = new Render3D(vp);
// actual startup
while (keepRunning) {
r3d.Init3D();
}
}
/// <summary>this method toggles the game runtime</summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void StartOrStop(object sender, RoutedEventArgs e) {
keepRunning = !keepRunning;
if (keepRunning) {
buttonStartStop.Content = "Stop";
// thread
t1 = new Thread( () => Runtime(myViewport) );
t1.Start();
}
else {
buttonStartStop.Content = "Start";
t1.Abort();
}
}
3DViewport 对象在 XAML 文件中初始化。这就是为什么我将它传递给新线程,它可以创建一个使用该 3DViewport 类的对象。
下面是该Render3D
课程的示例。
// constructor
internal Render3D(Viewport3D v) {
currViewport = v;
}
/// <summary>get called in loops to render gfx</summary>
internal void Init3D() {
// clear rendered view
ClearRenderWindow();
// add landscape
AddLandScape();
}
/// <summary>clear window to re-render gfx</summary>
private void ClearRenderWindow() {
ModelVisual3D mv;
// ***** error got caught here below ******
for (int i = currViewport.Children.Count - 1; i >= 0; i--) {
mv = (ModelVisual3D)currViewport.Children[i];
if (mv.Content is DirectionalLight == false) currViewport.Children.Remove(mv);
}
}
错误在currViewport.Children.Count
方法中被捕获。如前所述,问题在于当前线程没有该对象的所有权。这是我在多线程体验中第一次面对这个问题。我已经四处寻找,但找不到解决方案。
有谁知道如何传递 Viewport3D 对象的所有权,或者一个好的解决方法?