Я пишу программу редактирования карты для 2D игры с помощью XNA. Создать Texture2D для всех мозаик, которых требует карта, занимает слишком много времени.
Там какие-либо альтернативы к использованию структур для рисования с XNA?
Я попытался создать всего одну структуру на набор мозаики вместо структуры для каждой мозаики в наборе мозаики, но существует предел размеру структур, и я не мог соответствовать всем мозаикам набора мозаики в одну структуру.
В настоящее время программа содержит все потенциальные структуры в памяти, поскольку Битовый массив возражает. Существует ли способ просто потянуть Растровый объект на экран в XNA? Я искал, но я не могу найти информацию об этом. Этот подход избежал бы необходимости создавать структуры в целом, однако любая расцветка или эффекты, которые я должен был бы сделать к битовому массиву непосредственно.
К сожалению, насколько я знаю, в XNA нет возможности напрямую рисовать растровые изображения на экране; для этого требуется, чтобы все отображалось на объекты Texture, которые по умолчанию буферизуются на видеокарту. Похоже, что вы говорите о большом количестве плиток, однако, если все они не помещаются на максимально допустимой текстуре (не помню, 1024 или 4096 квадратов...) - пробовали ли вы использовать текстуру без буферизации для повышения скорости? Другой альтернативой может быть ленивая загрузка наборов тайлов в текстуры, чтобы пользователю не приходилось ждать, пока они все загрузятся - для редактора обычно приемлемо использовать ярко-розовый цвет отката, пока он загружается.
Кроме того, есть ли что-то, что изначально необходимо для написания вашего инструмента в XNA? Поскольку похоже, что вы пишете инструмент отдельно от самого игрового движка, вы можете найти некоторые вполне приемлемые решения в WPF, включая рисование непосредственно из BitmapSources и некоторые утилиты для вашего UI.
Предполагается, что все тайлы карты требуют существующих изображений, которые просто размещаются на экране, чтобы выложить карту тайлов? Или вы создаете изображения в этом редакторе карт и хотите сохранить их?
Я прочитал это и другое ваше сообщение о текстурах - Если это все готовые определенные изображения, которые вы хотите использовать в своей игре, не могли бы вы просто включить их в папку content и ссылаться на них там? Это позволит XNA скомпилировать текстуры в формате xnb, и у вас не будет проблем, о которых вы рассказываете.
Однако если мы говорим о полностью динамических текстурах - или вы создаете одно большое изображение из расположения плиток (вместо того, чтобы делать что-то вроде карты плиток), - то я не уверен, как подойти к этому вопросу.
Если несколько тайлов используют одну и ту же текстуру, достаточно загрузить ее только один раз.
Если пользователь включает текстуры в какой-либо формат файла, вы можете автоматически преобразовать его в формат текстуры / изображения, который подходит вам быстрее.
Поскольку вам необходимо использовать настраиваемый формат изображения, если вы хотите (для скорости), вы можете попытаться написать настраиваемые импортеры и процессоры конвейера содержимого для XNA ( http://msdn.microsoft.com/en-us /library/bb447754.aspx), но это может оказаться излишним для того, что вам нужно сделать.
Я вижу, вы хотите максимально упростить разработку графического интерфейса, даже если эти проблемы вынуждают вас использовать такой язык, как C ++, чтобы вы могли использовать DirectX. В Visual C ++ вы по-прежнему сможете использовать преимущества визуального макета Windows Forms , если вы используете Visual Studio.
Есть ли причина, по которой вы не рассматривали возможность загрузки изображения один раз, а затем передачи координат смещения 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();
}
}
Код шейдера может нуждаться в некотором встраивание в существующий код, но в противном случае он должен сделать трюк.
Вы пытаетесь нарисовать их все, используя один поток выполнения?
Попробуйте многопоточность вашей игры. Многопоточность в C # довольно проста и поддерживается XNA.
Вместо того, чтобы смотреть на экран в целом, попробуйте разделить его на две (или более) части. Возможно, вам придется переписать функцию, которую вы используете для Draw (я очень надеюсь, что вы не просто сбросили все прямо в свой метод Draw () !!), чтобы принять координаты, устанавливающие границы ваших областей рисования.