如果它很重要,我正在使用XNA 3.1,虽然如果4.0有很大帮助我可以考虑移动。
我正在尝试在游戏中绘制一个文本框。我希望能够只在文本框中显示文本(这样如果字符串更长,在文本框的边缘只显示部分字符)。
我遇到的问题是文本没有被剪裁,在这种情况下它只是在文本框的边界之外进行,或者使用这里描述的建议 - http://social.msdn.microsoft.com/forums/en-US/xnagamestudioexpress/thread/9c395c84-2257-4103-b75c-d9378425cc09 - 我发现如果我使用代码:
spriteBatch.GraphicsDevice.RenderState.ScissorTestEnable = true;
spriteBatch.GraphicsDevice.ScissorRectangle = myTextBox.GetRectangle();
我可以完全按照我的意愿在文本框中剪切它,但不幸的是,它根本没有在游戏中显示任何其他内容!建议使用ScissorRectangle的帖子说它需要在每个SpriteBatch上完成。这让我认为我需要一个新的SpriteBatch。我尝试使用现有的图形设备(新的SpriteBatch(spriteBath.GraphicsDevice))创建一个新的spriteBatch,然后修改它,但由于它是一个引用它有同样的问题,所以我觉得我需要克隆SpriteBatch或GraphicsDevice以某种方式对象,或创建一个新的GraphicsDevice(我不知道在后者的参数中放什么)。克隆方法不可用,有些东西告诉我,我有点复杂,所以这就是为什么我把所有这些背景都放在了。
如果我想显示带有剪切文本的文本框,那么这个ScissorRectangle的新SpriteBatch是最好的前进方式(它似乎运行良好),如果是这样,我该如何获得一个新的SpriteBatch以便我可以只显示我的文本框剪辑,但游戏的其余部分绘制得很好吗?我尝试在创建主游戏的同时创建一个新的spritebatch,但因为GraphicsDevice必须是相同的,所以我无法改变它,所以一个改变而另一个没有。
非常感谢。如果我错过了任何有用的细节,请告诉我 - 此时我不知道可能相关的内容。
答案 0 :(得分:3)
SpriteBatch
并非“拥有”该特定GraphicsDevice
。 GraphicsDevice
由游戏中的所有图形资源共享(这就是 设备的原因)。一般来说,应该只有GraphicsDevice
的一个实例。
因此,当您开启剪刀测试时,您正在启用所有的SpriteBatch
个对象。
答案很简单:再次关闭它!
你是正确的,你需要在一个单独的精灵批处理中执行此操作 - 它不需要是一个单独的SpriteBatch
对象!只是一个单独的Begin()
/ End()
块(这是“批处理”)。
更改SpriteBatch
在4.0版之前的XNA中使用的渲染状态有点棘手。 SpriteBatch
ScissorTestEnable
修改了哪些内容。请注意,SpriteBatch
不是其中之一,因此应将其设置为在之外。
这是因为End
可以在调用GraphicsDevice
之前对绘图进行排队 - 因此您对Draw
进行状态更改并在单个内部调用SpriteBatch
批处理的顺序可能与您预期的顺序不同。
(Begin()
管理的状态需要在XNA 4.0之前的版本中进行不同的修改。这有点难看。你必须SpriteSortMode.Immediate
{{1}然后然后进行更改。)
在XNA 4.0中,您可以将RasterizerState
ScissorTestEnable
设置为每个批次的Begin()
调用所需的值。理解它会容易得多。
答案 1 :(得分:2)
你不需要新的spritebatch ......
也许你没有禁用scissortest ...
要绘制剪辑文本,您必须执行与此类似的操作:
spriteBatch.GraphicsDevice.RenderState.ScissorTestEnable = true;
spriteBatch.GraphicsDevice.ScissorRectangle = myTextBox.GetRectangle();
spriteBacth.Begin();
spriteBatch.DrawString(...);
spriteBacth.End();
spriteBatch.GraphicsDevice.RenderState.ScissorTestEnable = false;
它也可以用模板缓冲区来完成,但是有点棘手......
这是我使用模板进行的实施测试:http://www.youtube.com/watch?v=-xUMC7sPAx0
这是剪刀测试的gui实现:http://www.youtube.com/watch?v=3pakgHjnScs
答案 2 :(得分:1)
有一个名为“Sprite batching”的概念和“spritebatch”对象。虽然两者密切相关,但我认为你误解了对象的概念。
具体来说,当你spritebatch.Begin并直到你spritebatch.End你创建(至少)1精灵批处理。此批次的许多设置可以设置为与您可能创建的任何其他批次不同的值。
如果你想创建更多的批次,你只需要更多的spritebatch.Begin ... .End序列。
在这种情况下,由于剪辑是一个精灵批处理效果,你必须在一个或多个构造(.Begin)和终止(.End)的批次中发送要剪切的所有内容 - 并将它们分别从任何批次发送其他批次你不想被剪裁。
简而言之,你最有可能:
这里希望这有助于您理解给予您的建议。
答案 3 :(得分:0)
您可以考虑使用RenderTarget2D将文本渲染为Texture2D,然后使用
只渲染此纹理的一部分SpriteBatch.Draw(Texture2D纹理,矩形目标,矩形源,颜色)
有关如何使用RenderTarget2D的更多信息,请查看以下链接: http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.rendertarget%28v=xnagamestudio.31%29.aspx
顺便说一句,完全值得切换到XNA 4.0 - 某些方法只有轻微的语法更改,但整体改进很棒。