Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在XNA中使用纹理有更快的替代方法吗?_C#_Xna_Textures - Fatal编程技术网

C# 在XNA中使用纹理有更快的替代方法吗?

C# 在XNA中使用纹理有更快的替代方法吗?,c#,xna,textures,C#,Xna,Textures,我正在使用XNA为2D游戏编写一个地图编辑程序。为贴图所需的所有平铺创建纹理2D需要花费太长时间 使用XNA绘制时,除了使用纹理,还有其他选择吗 我试图为每个瓷砖集创建一个纹理,而不是为瓷砖集中的每个瓷砖创建一个纹理,但是纹理的大小有限制,我无法将瓷砖集的所有瓷砖都放入一个纹理中 目前,该程序包含内存中作为位图对象的所有可能的纹理。有没有一种方法可以在XNA中简单地在屏幕上绘制位图对象?我已经搜索过了,但是我找不到关于这个的任何信息。这种方法可以避免完全创建纹理,但是我必须直接对位图进行任何着色

我正在使用XNA为2D游戏编写一个地图编辑程序。为贴图所需的所有平铺创建纹理2D需要花费太长时间

使用XNA绘制时,除了使用纹理,还有其他选择吗

我试图为每个瓷砖集创建一个纹理,而不是为瓷砖集中的每个瓷砖创建一个纹理,但是纹理的大小有限制,我无法将瓷砖集的所有瓷砖都放入一个纹理中


目前,该程序包含内存中作为位图对象的所有可能的纹理。有没有一种方法可以在XNA中简单地在屏幕上绘制位图对象?我已经搜索过了,但是我找不到关于这个的任何信息。这种方法可以避免完全创建纹理,但是我必须直接对位图进行任何着色或效果。

假设贴图所需的所有分幅都是现有图像,而这些图像只是放置在屏幕上以布局分幅贴图?或者您正在使用此地图编辑器制作图像并希望将其保存

我读了这篇文章,还有你的另一篇关于纹理的文章——如果它们都是你想在游戏中使用的现成定义的图像,你就不能将它们包含在内容文件夹中并在那里引用它们吗?这允许XNA以xnb格式编译纹理,您不应该有您正在解释的问题


但是,如果我们谈论的是完全动态的,或者您正在从瓷砖的布局中制作一个大图像(而不是像瓷砖地图那样做),那么我不知道如何处理这个问题。

如果多个瓷砖使用相同的纹理,只需加载一次就足够了


如果用户包含某些文件格式的纹理,您可以自动将其转换为满足您需要的更快的纹理/图像格式。

由于您需要使用自定义图像格式,如果您希望(为了速度),您可以尝试为XNA()编写自定义内容管道导入器和处理器,但对于你需要做的事情来说,这可能是过分的


<>我看到你想尽可能容易地设计GUI,即使这些问题强迫你使用C++语言,你也可以使用DirectX。在VisualC++中,如果使用VisualStudio.

,你仍然可以利用它,不幸的是,据我所知,没有办法直接在XNA中绘制位图到屏幕上;它要求所有内容都映射到纹理对象,默认情况下,纹理对象缓冲到图形卡。听起来你说的是很多瓷砖,但是,如果它们不都适合最大允许的纹理(我不记得是1024还是4096平方…)-你有没有尝试过使用无缓冲纹理来提高速度?另一种选择是将瓷砖集延迟加载到纹理中,这样用户就不必等待它们全部加载-对于编辑器,在加载时使用亮粉色回退颜色通常是可以接受的


另外,在XNA中编写工具是否有内在的要求?由于听起来您是在独立于游戏引擎本身编写工具,因此您可能会在WPF中找到一些非常可接受的解决方案,包括直接从BitmapSources和一些用于UI的实用程序进行绘制。

您是否尝试使用单线程执行来绘制它们

尝试多线程游戏。C#中的线程非常简单,XNA支持


不要把你的屏幕看作一个整体,试着把它分成两个(或更多)部分。您可能需要重新编写用于绘制的函数(我当然希望您不只是直接在Draw()方法中转储所有内容!!),以获取设置绘制区域边界的坐标

是否有任何理由不考虑加载一次图像,然后将x和y偏移坐标传递给像素着色器

基本上,您可以这样设置C#:

myGraphicsDevice.Textures[0] = whateverYourGiantMapTextureIs;

foreach(MapChunk chunk in mapChunks) {
    myShader.Effect.Parameters["xOffset"] = chunk.XOffset;
    myShader.Effect.Parameters["yOffset"] = chunk.YOffset;

    myGraphicsDevice.DrawIndexedPrimitives( your chunk drawing code here );
}
float4x4 World; 
float4x4 View; 
float4x4 Projection;

float xOffset;
float yOffset;

sampler TextureSampler; 

struct VS_INPUT { 
    float4 Position : POSITION0; 
    float4 Color    : COLOR0;
};

VS_INPUT Transform(VS_INPUT Input) { 
    VS_INPUT Output; 

    float4 worldPosition = mul(Input.Position, World); 
    float4 viewPosition = mul(worldPosition, View); 
    Output.Position = mul(viewPosition, Projection); 
    Output.Color = Input.Color;

    return Output; 
} 

float4 ColorTexture(VS_INPUT Input) : COLOR0{ 
    return Input.Color.rgba * tex2D(TextureSampler, float2(xOffset, yOffset));
} 

technique TransformColorTexture { 
    pass P0 { 
        VertexShader = compile vs_2_0 Transform(); 
        PixelShader = compile ps_2_0 ColorTexture(); 
    } 
}
然后着色器代码如下所示:

myGraphicsDevice.Textures[0] = whateverYourGiantMapTextureIs;

foreach(MapChunk chunk in mapChunks) {
    myShader.Effect.Parameters["xOffset"] = chunk.XOffset;
    myShader.Effect.Parameters["yOffset"] = chunk.YOffset;

    myGraphicsDevice.DrawIndexedPrimitives( your chunk drawing code here );
}
float4x4 World; 
float4x4 View; 
float4x4 Projection;

float xOffset;
float yOffset;

sampler TextureSampler; 

struct VS_INPUT { 
    float4 Position : POSITION0; 
    float4 Color    : COLOR0;
};

VS_INPUT Transform(VS_INPUT Input) { 
    VS_INPUT Output; 

    float4 worldPosition = mul(Input.Position, World); 
    float4 viewPosition = mul(worldPosition, View); 
    Output.Position = mul(viewPosition, Projection); 
    Output.Color = Input.Color;

    return Output; 
} 

float4 ColorTexture(VS_INPUT Input) : COLOR0{ 
    return Input.Color.rgba * tex2D(TextureSampler, float2(xOffset, yOffset));
} 

technique TransformColorTexture { 
    pass P0 { 
        VertexShader = compile vs_2_0 Transform(); 
        PixelShader = compile ps_2_0 ColorTexture(); 
    } 
}

着色器代码可能需要在现有代码中进行一些拟合,但如果不是这样的话,它应该可以做到这一点。

使用每个平铺一个纹理不是很有效。特别是因为这意味着你不能进行批处理(在任何真正意义上)

如果出于某种原因(更容易编辑一个平铺等),您需要在内容项目中将它们作为单独的纹理,则可以在加载后非常轻松地将它们编译为平铺贴图。 你如何做到这一点基本上是:

1:加载多个瓷砖(现在假设为40 32*32瓷砖)

2:为tilemap找到一个好的纹理大小: 40的平方根是6.5左右,所以我们四舍五入到7。7*32是224,这很好,但是256更好,所以让我们制作纹理256x256。(您可以编写代码,在运行中解决此问题)

3:创建所需大小的Rendertarget2D

4:激活渲染目标

5:在渲染目标上渲染分片:

int x, y = 0;
foreach (var tile in allTiles)
{
    RenderTile(tile, x*32, y*32);
    x++;

    if (x >= 8)
    {
        x = 0;
        y++;
    }
}
若要进行betch渲染,请使用具有4*40个顶点的顶点缓冲区。每组4都有一个值,指示它所属的四元组的索引(0、1、2等)。在着色器中,有一个矩阵数组[40]用于确定瓷砖的位置,还有一个tileIndex数组(int[40]),用于知道要从tilemap渲染哪个瓷砖

很抱歉,我现在没有时间写所有的着色器代码:s


我在游戏中使用的另一个技巧是在大瓷砖(640x360)上预渲染关卡,这大大减少了平局调用的数量,特别是在处理来自不同瓷砖集的5+层瓷砖时。唯一的问题是,它不适用于动态瓷砖(动画瓷砖等),但您可以标记它们并正常渲染它们,如果您需要…

您好,感谢您的回复。简单地将图像文件添加到内容文件夹的问题在于它们是自定义格式的图像-我的地图编辑器适用于使用这些图像的现有游戏。我希望能够使用C语言和XNA对编辑器进行编码,但是现在看来我必须重新启动,使用C++和DirectX来完成它。