日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪(fǎng)問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

在Browser Application中使用XNA

發(fā)布時(shí)間:2025/3/17 编程问答 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 在Browser Application中使用XNA 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在WPF中,我們使用Mode3D等API來(lái)繪制三維場(chǎng)景,當(dāng)期間的“三角形”超過(guò)一定數(shù)量時(shí),整個(gè)場(chǎng)景的渲染速率直線(xiàn)下降,無(wú)論顯卡的運(yùn)行速度有多快,幀率都維持在3、5幀每秒。

XNA是微軟推出的一套游戲開(kāi)發(fā)API,作為Managed DirectX的進(jìn)化版,XNA同樣封裝了DirectX的底層API,此外還提供了一系列和游戲生命周期相關(guān)的類(lèi),大大減輕了傳統(tǒng)Win32下DirectX開(kāi)發(fā)的煩瑣。

本文試圖讓XNA“嵌入”在WPF的Browser Application中,使用XNA來(lái)渲染場(chǎng)景,并以XBAP的方式在互聯(lián)網(wǎng)上發(fā)布,集XNA的高效和WPF的部署方便為一生,免除了開(kāi)發(fā)人員在部署、安裝、升級(jí)應(yīng)用程序的困擾。

建立應(yīng)用程序

首先建立一個(gè)空白解決方案:

為它添加一個(gè)XNA應(yīng)用程序,一個(gè)WPF Webbrowser 應(yīng)用程序:

在XNA上畫(huà)一個(gè)人物模型:

在Browser Application中使用XNA

為Browser Application添加相關(guān)引用:

使用Winform的Panel

修改頁(yè)面文件,在上面添加一個(gè)和一個(gè)Winform的Panel:

<Page x:Class="Newinfosoft.Test.Browser.XNAPage"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:form="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"Title="XNA Page" Loaded="Page_Loaded"><Grid><WindowsFormsHost Margin="0,0,0,30"><form:Panel x:Name="drawPanel" /></WindowsFormsHost></Grid> </Page>

由于我們?cè)贐rowser Application中使用了Win32的資源,因此,需要修改其安全性,最簡(jiǎn)答的方式是將安全性設(shè)置為完全信任(Full Trust)

接下來(lái),修改XNA應(yīng)用程序的構(gòu)造函數(shù),傳入一個(gè)IntPtr類(lèi)型(實(shí)際上是窗體指針),并把渲染的Handle設(shè)置為該地址:

public XNAGame(IntPtr handle) {graphics = new GraphicsDeviceManager(this);Content.RootDirectory = "Content";graphics.PreferredBackBufferWidth = 480;graphics.PreferredBackBufferHeight = 320;graphics.PreparingDeviceSettings += (sender, e) =>{e.GraphicsDeviceInformation.PresentationParameters.DeviceWindowHandle = handle;}; }

修改Browser Application,在Page加載時(shí)運(yùn)行游戲:

private void Page_Loaded(object sender, RoutedEventArgs e) {XNAGame game = new XNAGame(drawPanel.Handle);game.Run(); }

效果如下:

如果你不想見(jiàn)到那個(gè)游戲的原生窗口,可以在XNAGame的構(gòu)造函數(shù)中把原生窗口隱藏起來(lái):

public XNAGame(IntPtr handle) {graphics = new GraphicsDeviceManager(this);Content.RootDirectory = "Content";graphics.PreferredBackBufferWidth = 480;graphics.PreferredBackBufferHeight = 320;graphics.PreparingDeviceSettings += (sender, e) =>{e.GraphicsDeviceInformation.PresentationParameters.DeviceWindowHandle = handle;};System.Windows.Forms.Form form = (System.Windows.Forms.Form)System.Windows.Forms.Control.FromHandle((this.Window.Handle));form.Visible = false;form.VisibleChanged += (sender, e) =>{(sender as System.Windows.Forms.Form).Visible = false;}; }

缺點(diǎn)

使用Win32原生窗口,好處在于簡(jiǎn)單、高效。但缺點(diǎn)是,原生窗口打破了WPF的Z-Order,往往會(huì)伏在WPF控件上方,例如,在上面添加一個(gè)按鈕,設(shè)計(jì)效果如下:

運(yùn)行時(shí),發(fā)現(xiàn)Panel反而跑到按鈕上面去了:

這是由于二者采用不同的渲染模式,具體參見(jiàn):The WPF Interoperation: “Airspace” and Windows Regions Overview

使用D3DImage

所幸WPF提供了一個(gè)D3DImage的ImageSource,負(fù)責(zé)在WPF中承載d3d,既然XNA底層封裝了d3d,那么,是不是WPF也能通過(guò)D3DImage承載XNA?答案是肯定的。

修改XNAGame,為它添加兩個(gè)事件,Init和DrawEnd:

public event EventHandler Init; public event EventHandler DrawEnd;

添加一個(gè)RenderTarget2D對(duì)象,讓XNA把渲染的結(jié)果保存在其中,而不是back buffer里。

public RenderTarget2D RenderTarget { get;protected set; }

在Initialize函數(shù)中初始化這個(gè)RenderTarget2D對(duì)象,并使用事件Init通知其他程序。

protected override void Initialize() {// TODO: Add your initialization logic herebase.Initialize();RenderTarget = new RenderTarget2D(graphics.GraphicsDevice,graphics.GraphicsDevice.Viewport.Width,graphics.GraphicsDevice.Viewport.Height,1,SurfaceFormat.Color);GraphicsDevice.SetRenderTarget(0, RenderTarget);if (Init != null){Init(this, new EventArgs());} }

在Draw函數(shù)的最后,使用事件DrawEnd來(lái)通知其他程序,完成一幀的渲染:

protected override void Draw(GameTime gameTime) {GraphicsDevice.Clear(Color.CornflowerBlue);// …?…?…?…?base.Draw(gameTime);if (this.DrawEnd != null){DrawEnd(this, new EventArgs());} }

修改Page,使用Image控件代替WindowsFormsHost:

<Page x:Class="Newinfosoft.Test.Browser.XNAPage"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"Title="XNA Page"><Grid><Image x:Name="image" Margin="0,0,0,30"Source="start.png"MouseLeftButtonUp="image_MouseLeftButtonUp" /><Button Content="Click Me"VerticalAlignment="Bottom"Margin="0,0,0,10"HorizontalAlignment="Center"Padding="10"></Button></Grid> </Page>

以上代碼中,用了一個(gè)hack,即首先為該Image控件設(shè)定一個(gè)ImageSource,同樣的,把創(chuàng)建XNAGame的步驟從Page.Load中轉(zhuǎn)移到鼠標(biāo)點(diǎn)擊該Image上,由于不再使用WinForm的Panel,因此,使用一個(gè)HwndSource對(duì)象作為Game的載體:

private void image_MouseLeftButtonUp(object sender, MouseButtonEventArgs e) {image.MouseLeftButtonUp-=new MouseButtonEventHandler(image_MouseLeftButtonUp);HwndSource hwnd = new HwndSource(0, 0, 0, 0, 0, "test", IntPtr.Zero);XNAGame game = new XNAGame(hwnd.Handle);game.Init += new EventHandler(game_Init);game.Run(); }

添加一個(gè)D3DImage對(duì)象:

D3DImage d3dimage = new D3DImage();

在game_Init中初始化該d3dimage的后臺(tái)緩存:

void game_Init(object sender, EventArgs e) {XNAGame game = sender as XNAGame;if (d3dimage.IsFrontBufferAvailable){d3dimage.Lock();d3dimage.SetBackBuffer(D3DResourceType.IDirect3DSurface9,GetRenderTargetPointer(game.RenderTarget));d3dimage.Unlock();image.Source = d3dimage;}image.Source = d3dimage;game.DrawEnd += new EventHandler(game_DrawEnd); }

GetRenderTargetPointer定義如下,利用反射的機(jī)制取得RenderTarget2D的內(nèi)存地址:

public unsafe IntPtr GetRenderTargetPointer(RenderTarget2D renderTarget) {FieldInfo comPtr = renderTarget.GetType().GetField("pComPtr",BindingFlags.NonPublic | BindingFlags.Instance);return new IntPtr(Pointer.Unbox(comPtr.GetValue(renderTarget))); }

?

?

?

?

?

最后,在game_DrawEnd函數(shù)中更新d3dimage:

void game_DrawEnd(object sender, EventArgs e) {if (d3dimage.IsFrontBufferAvailable){d3dimage.Lock();d3dimage.AddDirtyRect(new Int32Rect(0, 0, d3dimage.PixelWidth, d3dimage.PixelHeight));d3dimage.Unlock();} }

運(yùn)行結(jié)果,我們發(fā)現(xiàn)游戲畫(huà)面不再阻擋Button了:

與50位技術(shù)專(zhuān)家面對(duì)面20年技術(shù)見(jiàn)證,附贈(zèng)技術(shù)全景圖

總結(jié)

以上是生活随笔為你收集整理的在Browser Application中使用XNA的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

主站蜘蛛池模板: 日韩黄色三级视频 | av一起看香蕉 | 合欢视频在线观看 | 涩涩视频在线播放 | 国产精品无码久久久久一区二区 | 九九热视频在线播放 | www.麻豆av.com | 国产成人短视频 | 欧美一级在线看 | 国产经典久久 | a天堂最新地址 | 麻豆www.| 色人阁五月天 | 在线国产精品视频 | av成人在线观看 | 99这里有精品 | 婷久久| 国产成人无码a区在线观看视频 | 国产男人搡女人免费视频 | 香蕉视频A | 国产精品福利网站 | 伊人3| 男生和女生差差视频 | 中文字幕国产精品 | 激情小视频 | 加勒比在线免费视频 | 欧美成人手机视频 | 91丨porny丨海角社区 | 99久久免费国产精精品 | 男人天堂久久 | 爱爱三级视频 | 国产4区 | 成人精品免费在线观看 | 精品久久在线 | 日韩av片在线看 | 午夜男人影院 | 色播五月综合 | 麻豆视频网| 少妇无码一区二区三区免费 | 黄色日批网站 | 中文字幕亚洲乱码熟女一区二区 | 欧美一级日韩一级 | 亚洲免费毛片 | 欧美一区二区三区影视 | 欧美日韩中 | 麻豆一区二区三区四区 | 久久av一区二区三 | 欧美福利视频一区二区 | 淫五月天| 亚洲黄色av | 亚洲图片在线视频 | 天天成人 | 国产人免费人成免费视频 | 中文字幕一区久久 | 成人欧美一区二区三区黑人一 | 国产黑丝在线 | 呦呦网| av在线看片 | 天天搞天天 | 欧美 丝袜 自拍 制服 另类 | 国产免费高清视频 | 国产免费a | 五月六月婷婷 | 少妇人妻偷人精品一区二区 | 国产传媒视频在线观看 | 视频一区二区三区精品 | 国产夜色视频 | 日韩天堂视频 | 蜜桃视频在线观看www | 美女黄视频网站 | 欧美激情在线观看视频 | aa一级片 | 九色.com| 欧美丰满熟妇bbbbbb百度 | 亚洲自拍p | 午夜精品小视频 | 日韩av影片在线观看 | 拔插拔插海外华人免费视频 | av毛片观看 | 亚洲午夜剧场 | 伊人超碰在线 | 欧美日韩一区电影 | 恶虐女帝安卓汉化版最新版本 | 毛片无遮挡高清免费观看 | 亚洲午夜在线播放 | 熟妇人妻精品一区二区三区视频 | 狠狠躁18三区二区一区 | 91香蕉久久 | 国产九九在线 | 亚洲三级伦理 | 色又色 | 色丁香在线 | 久久高清无码电影 | 深爱五月激情网 | 亚洲三级免费观看 | 亚洲一区二区高清 | 日韩国产三级 | 亚洲精品乱码久久久久久蜜桃欧美 | 性猛交富婆╳xxx乱大交麻豆 |