【问题标题】:Can't get an Awesomium render onto the screen in XNA无法在 XNA 中将 Awesomium 渲染到屏幕上
【发布时间】:2012-08-24 12:16:06
【问题描述】:

我目前正在使用有人建议将 Awesomium 和 XNA 结合使用的 this 代码,但是我遇到了一个问题...每当我尝试绘制组件给我的结果 Texture2d 时,我得到:

您不能在 GraphicsDevice 上主动设置资源时调用 SetData。在调用 SetData 之前从设备中取消设置。

这是我的代码:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Awesomium.Core;

namespace ProjectTest
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;
        AwesomiumComponent uiHud;

        public Game1()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";
            Rectangle rect = new Rectangle(100, 100, 500, 500);
            uiHud = new AwesomiumComponent(this, rect);
            this.Components.Add(uiHud);
        }

        /// <summary>
        /// Allows the game to perform any initialization it needs to before starting to run.
        /// This is where it can query for any required services and load any non-graphic
        /// related content.  Calling base.Initialize will enumerate through any components
        /// and initialize them as well.
        /// </summary>
        protected override void Initialize()
        {
            // TODO: Add your initialization logic here

            base.Initialize();
        }

        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            uiHud.WebView.LoadURL("http://www.google.com/");

            // TODO: use this.Content to load your game content here
        }

        /// <summary>
        /// UnloadContent will be called once per game and is the place to unload
        /// all content.
        /// </summary>
        protected override void UnloadContent()
        {
            // TODO: Unload any non ContentManager content here
        }

        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                this.Exit();

            // TODO: Add your update logic here
            //uiHud.Update(gameTime);

            base.Update(gameTime);
        }

        /// <summary>
        /// This is called when the game should draw itself.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);
            Vector2 pos = new Vector2(10, 10);


            spriteBatch.Begin();
            spriteBatch.Draw(uiHud.WebViewTexture, pos, Color.White);
            spriteBatch.End();

            //uiHud.Draw(gameTime);
            // TODO: Add your drawing code here
            base.Draw(gameTime);
        }
    }
}

我到底做错了什么?

【问题讨论】:

  • 你确定你应该用 spritebatch 绘制你的 hud 吗?看起来组件本身暴露了一个Draw 方法。您是否尝试过使用它?
  • @Dervall 我试过了,但我很确定它不是这样工作的。另外,当我这样做时,什么也没有出现。

标签: c# xna awesomium


【解决方案1】:

您的SpriteBatch 正在将网络纹理设置到图形设备的第一个纹理阶段,并且永远不会取消设置。这导致 Awesomium 的 Draw() 方法失败,因为它试图在仍在使用的纹理上调用 SetData()

spriteBatch.End()之后,取消设置纹理阶段:

GraphicsDevice.Textures[0] = null;

【讨论】:

  • 哇,这确实有效......但是有没有更简单的解决方案?甚至编辑组件。一旦我开始使用大量纹理,您的解决方案似乎就行不通了,更不用说其他可能的问题了(?)
  • 您正在使用的纹理数量无关紧要;只涉及一个纹理阶段。您需要在调用组件的Draw() 方法之前取消设置该阶段,或者使用不同的纹理绘制一些东西,以便为您取消设置纹理。我怀疑后者会成为更自然的解决方案。
  • 只是呼应 Cole 的评论,即它根本不是 hacky。基本上所有的渲染都是通过在图形设备上设置各种状态,然后调用它的Draw 方法之一来实际触发绘图来实现的。 SpriteBatch 实际上是在其易于使用的包装器中执行 GraphicsDevice.Textures[0] = yourTexture(以及其他一些事情)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-28
相关资源
最近更新 更多