2012-03-10 32 views
0

我在本周早些时候提出了一个问题(here),有关将数据从rendertarget传输到CPU,以便可以对其进行测试。从我得到的回复中,我决定将渲染目标的一部分绘制为较小的渲染目标,然后检索该数据将是一个有效的解决方案,并试图实现该目标。如何从一个渲染目标绘制一个矩形而不丢失数据?

在绘制完整尺寸的渲染目标(1280x1024)之后,我将活动渲染目标切换到较小的目标(59X47 - 我的玩家的碰撞大小)并尝试绘制大于渲染目标的部分玩家进入更小的目标。起初,我认为这是有效的,但后来我发现碰撞有时会非常不准确。

我画了一个较小的渲染目标到屏幕来检查它的内容,发现它在任何时候都只有少量像素被占用,而且这些像素总是在左上角。

  // Render rectangle under player from foreground to collision layer 
      Rectangle sourceRectangle = new Rectangle(sourceX, sourceY, 
                 (int)sizeX, (int)sizeY); 
      gd.SetRenderTarget(collisionLayer[i]); 
      gd.Clear(Color.Transparent); 
      spriteBatch.Draw(foregroundLayer, collisionLayer[i].Bounds, 
               sourceRectangle, Color.White); 
      gd.SetRenderTarget(null); 

绘制完整的大型渲染目标在结转成功的数据更小的目标结果(尽管比例,很明显),所以我不知道什么错误。

  // Render full target onto collision layer 
      gd.SetRenderTarget(collisionLayer[i]); 
      gd.Clear(Color.Transparent); 
      spriteBatch.Draw(foregroundLayer,new Vector2(0.0f),Color.White); 
      gd.SetRenderTarget(null); 

下图显示了在左上角叠加小目标的大目标。大型目标的全部数据似乎被正确绘制。

+0

图片显示的东西不工作?它对我来说看起来相当正确 - 小图像似乎是大图的一个很好的表现。你将从1280x1024下降到59x47。当尺度变化很大时,你不能指望一幅完美的小图像。 – 2012-03-10 14:33:44

+0

如果在问题中不清楚,我很抱歉。问题在于,在复制完整图像的同时,我无法抓住玩家下方的矩形。如果我要使用第一个代码段,那么在这种情况下,左上角的图片应该是空白的,因为没有玩家坐在黑色墨水上(纸张纹理不可碰撞)并且包含黑色像素, 1,如果他们在墨水印迹上,则图像在播放器下方。我实际得到的数据似乎并没有涉及到数据,因为我只是得到了几个黑色的像素(0,0)。 – LlamaCloud 2012-03-10 14:47:11

+0

我没有看到你显示的代码有任何明显的错误。我想我的第一个预感是你的sourceRectangle不是你期望的那样。你是否努力将矩形编码到你认识的地方,并看到结果如何? – 2012-03-10 15:09:56

回答

2

你不显示您spriteBatch.BeginspriteBatch.End通话,但它看起来像你需要移动它们。具体来说,您在调用spriteBatch.End之前将渲染目标设置为null,或者至少在您的示例代码中看起来如此。

我建立了一个示例项目,当我做下面一切正常......

GraphicsDevice.SetRenderTarget(target); 
    GraphicsDevice.Clear(Color.Transparent); 
    spriteBatch.Begin(); 
    spriteBatch.Draw(texture, target.Bounds, new Rectangle(50, 500, 100, 100), Color.White); 
    spriteBatch.End(); 

    GraphicsDevice.SetRenderTarget(null); 
    GraphicsDevice.Clear(Color.CornflowerBlue); 
    spriteBatch.Begin(); 
    spriteBatch.Draw(texture, new Rectangle(0, 0, 640, 480), texture.Bounds, Color.White); 
    spriteBatch.Draw(target, Vector2.Zero, target.Bounds, Color.White); 
    spriteBatch.End(); 

但如果我SetRenderTarget(null)后移至spriteBatch.End我的渲​​染目标是空的。

+0

Sprite批处理很久以前就开始了,并且在这之后从哪里结束了更长的时间,但我没有看到任何理由,为什么我们不能只是改变它,以便渲染过程的不同部分根据需要开始和结束批处理。直到明天我才会离开这个项目,但是我会尝试一下,如果可行的话,我会接受你的答案。谢谢你的帮助。 – LlamaCloud 2012-03-11 13:29:58

+0

结束'SpriteBatch'就是实际的绘图,所以在你改变渲染目标后结束它,你要么绘制错误的渲染目标,要么你的绘制调用会丢失 - 不知道是哪一个。实际上,'SpriteBatch'可以跟踪它绘制的渲染目标,但仍然可以通过'End'调用刷新调用,所以如果你不调用它,绘图不会发生。 – 2012-03-11 13:33:23

+0

我刚刚开始调用并开始调用(将绘图分成几个批次),并且完美运行。非常感谢你的协助。 – LlamaCloud 2012-03-12 11:57:12