My problem is the I need to represent a length-changing floor using a Texture2D, which means a floor that the sides has the image of the sides, and in the middle it repeats the same 'middle' image, like so:
To achieve this, I get the 'left edge', the 'middle' and the 'right edge' textures, problem is I don't know how to merge them into one single texture2D,
It is important to do that at run-time because the floor length is changing (horizontally),
I read you can do that using SetData but I have no idea how...
It is very important for me that it will act as one texture and not multiple texture parts because I am using Farseer Physics Engine to move the floor and use it.
I am using C# and XNA with Visual Studio 2010, I am an almost-experienced C# programmer,
Thank you!
This answer may help you. Either you should use HLSL for repeating your floor or you should draw your floor on a RenderTarget and save it as single Texture. Enjoy.
First, create a new Texture2D to serve as your floor texture, specifying the appropriate width and height. Then, get the data of the three textures you want to merge, using the GetData method. Finally, use the SetData method to set the data of the new texture as appropriate (check the link, you can specify the start index).
Warning: GetData and SetData methods are slow. If you need to create this texture only once per game (at the initialization for example), it's not a problem, though.
You are using farseer... but it does not prohibit you to use a tiling approach...
I don't know farseer, but I suppose that it provide a transform matrix...
do:
Vector2 pos = Vector2.Zero;
spriteBatch.Begin(...,....,...,..., Transform);
spriteBatch.Draw(LeftTexture, pos, null, Color.White);
pos.X += LeftTexture.Width;
for (int i=0; i<floor_repeats; i++)
{
spriteBatch.Draw(MidleTexture, pos , null, Color.White);
pos.X += MiddleTexture.Width;
}
spriteBatch.Draw(RightTexture, pos , null, Color.White);
Related
So as you see in the picture, i made a texture repeat on a rectangle(its size is 40,10,60) but it repeat the same amount of time on every face,so depending of the size of the face the texture is stretched.
In the picture you see that on the top face the texture repeat correctly and keep its original size but on the other faces it is streched.
Is there a way to repeat the texture without changing its size ?
Thank you for your responses.
screen of the problem
Edit : this script in c# does exactly what i want but is there a way to do it without a script since it was done in 2017 ?
https://github.com/Dsphar/Cube_Texture_Auto_Repeat_Unity/blob/master/ReCalcCubeTexture.cs
Unfortunately you will probably need to create a new material with the same image for each different scale using the 'Tiling' attribute:
*** Edit #1
The x and y Tiling values need to proportional to the scale of the plane or it will stretch.
If the size of the mesh being textured is static, you can change its UVs in a 3d program. You could even change the UVs via script.
Another option would be to look into worldspace (triplanar) shaders. These texture based on world position rather than the vertices local position.
If you are using Shader Graph, look at the triplanar node.
https://docs.unity3d.com/Packages/com.unity.shadergraph#6.9/manual/Triplanar-Node.html
How can I render text in the form of an isometric projection? I understand the principle but I'm not sure how to actually transform a SpriteFont programmatically to do this.
Example of what I mean:
I'm not even sure what I should be searching for. It seems I could accomplish this by using an isometric projection matrix and a 3D mesh font, but that seems overcomplicated considering I'm working in 2D.
Any ideas?
SpriteBatch.Begin takes a Matrix parameter, transforming the sprites you draw (including SpriteFont) onto whichever plane you desire.
Unfortunately Matrix does not provide Create* methods for creating skew matrices. But it is simple enough to create such a matrix by hand. The following piece of code is tested and is pretty close to what you want:
Matrix skew = Matrix.Identity;
skew.M12 = (float)Math.Tan(MathHelper.ToRadians(36.87f));
Matrix rotate = Matrix.CreateRotationZ(MathHelper.ToRadians(270+26.565f));
sb.Begin(SpriteSortMode.Deferred, null, null, null, null, null, skew * rotate);
// ... draw your sprites here ...
sb.End();
The only difference to your diagram is that Y and Y' point in the opposite direction, because XNA's SpriteBatch works in "client" coordinates ((0,0) at top left, and Y+ is down).
You can use a matrix transformation together with a sprite batch to achieve this. You can read more about matrix translation here.
what is the best way to position the Camera in a way that i can see what i paint in a certain region?
p.e. I'm painting a rectangle at around 300,400,2200. Where do i have to place the camera and which view do i have to set so that everything fits "in"?
Is there a trick or a special method or do i have to try it out with different camera positions?
There is no standard function that will position the camera this way because there are many options (think of different sides and rotations)
A trick you could use is:
Take the center of the MeshGeometry3D by using the Bounds property and add the normal vector several times to position the Camera.
Then use the normal vector of the plane, invert it and use it as the LookDirection for the camera.
How far you need to move the camera depends on the view angle of the camera. It can be calculated. Let me know if you want to know how (it will take me a little extra time)
More information can be found here too
I am writing a map editing program for a 2D game using XNA. To create a Texture2D for all of the tiles that a map requires takes too long.
Are there any alternatives to using textures for drawing with XNA?
I attempted to create just one texture per tile set instead of a texture for every tile in a tile set, but there is a limit to the size of textures and I could not fit all the tiles of a tile set into one texture.
Currently the program contains all the would-be textures in memory as Bitmap objects. Is there a way to simply draw a Bitmap object to the screen in XNA? I have searched but I cannot find any information on this. This approach would avoid having to create textures altogether, however any tinting or effects I would have to do to the bitmap directly.
Is there any reason you haven't considered loading the image one time and then passing in x and y offset coordinates to the pixel shader?
You would basically set the C# up like this:
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 );
}
And then the shader code like this:
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();
}
}
The shader code might need some fitting into your existing code but otherwise it should do the trick.
Using one texture per tile is not very efficient. Especially since it means you cannot do batching (in any real sense).
If you NEED to have them as separate textures in your content-project for some reason (easier to edit one tile, etc), you can quite easily compile them into tilemaps after loading.
How you do this is basicly:
1: Load a number of tiles (lets say 40 32*32 tiles for now)
2: Figure out a nice texture-size for the tilemap:
square root of 40 is 6.something, so we round up to 7. 7*32 is 224, which is nice, but 256 is nicer, so lets make the texture 256x256. (you can make code that figures out this on the fly)
3: Create a Rendertarget2D which is the desired size.
4: Activate rendertarget.
5: Render tiles on rendertarget:
int x, y = 0;
foreach (var tile in allTiles)
{
RenderTile(tile, x*32, y*32);
x++;
if (x >= 8)
{
x = 0;
y++;
}
}
To betch-render you have a vertex-buffer with 4 * 40 vertices. each set of 4 has a value indicating index of the quad it belongs to (0,1,2,etc...). In your shader you have an array of matrixes[40] for position of the tiles, as well as an array of tileIndex (int[40]) for knowing which tile to render from the tilemap.
I'm sorry, but I don't have time to write all the shader-code right now :s
An other trick I have used in our games is pre-rendering the level onto large tiles (640x360), which reduces the number of draw-calls by a great deal, especially when dealing with 5+ layers of tiles from different tilesets. Only thing is that it does not work with dynamic tiles (animated tiles, etc), but you can mark those and render them normally if you want...
Since you need to use a custom image format, if you want (for speed) you can attempt to write custom content pipeline importers and processors for XNA ( http://msdn.microsoft.com/en-us/library/bb447754.aspx ), but this may be overkill for what you need to do.
I see you want to design the GUI as easily as possible, even if these issues force you to use a language like C++ so you can use DirectX. In Visual C++ you should still be able to take advantage of visual Windows Forms layout if you are using Visual Studio.
Unfortunately, as far as I know, there is no way to directly draw a bitmap to the screen in XNA; it requires that everything is mapped to the Texture objects, which are by default buffered to the graphics card. It sounds like you're talking about a lot of tiles, though, if they won't all fit on the maximum allowed texture (I can't remember whether that was 1024 or 4096 square...) - have you tried having an unbuffered texture for speed purposes? Another alternative would be to lazy-load your tilesets into textures so the user didn't have to wait for them all to load - for an editor, using a bright pink fallback color is usually acceptable while it loads.
Also, is there anything inherently required to write your tool in XNA? Since it sounds like you're writing the tool separately from the game engine itself, you may find some very acceptable solutions in WPF, including drawing directly from BitmapSources and some utilities for your UI.
Assuming all the tiles that a map require existing images that are simply placing on a screen to lay out a tile map? Or are you making images in this map editor and want to save them out?
I read this, and your other post about textures - If they are all ready defined images that you want to use in your game couldnt you just include them in the content folder and reference them there? This allows XNA to compile the textures in the xnb format and you shouldn't have the problems you are explaining.
However if we are talking completely dynamic - or you are crafting one big image from the layout of the tiles (instead of doing something like a tile map) then I am not sure how to approach the issue.
If multiple tiles use the same texture, it will be enough to load it just once.
If the user includes textures in some file format, you could automatically convert it to a texture/image format which is faster for your needs.
Are you trying draw them all using a single thread of execution?
Try multi-threading your game. Threading in C# is quite easy and is supported by XNA.
Instead of looking at your screen as a whole, try splitting it into two (or more) portions. You may need to re-write the function you're using to Draw (I sure hope you didn't just dump everything directly in your Draw() method!!) to take in coordinates setting the boundaries of your draw regions.
I'm quite new to the world of 2D-Engines. I figured out how to load images and display those as sprites and stuff, but theres one question that bugs me.
For instance, when a "rocket" hits an object it will deal damage to it and leave a crater behind. I'd like to have the crater shown on that object. That would require "skipping" some of the pixels of that image when rendering, doesn't it?
My question is, how would you do such a thing? What data strcture would you use to save this? How to display a "broken" sprite?
Create a sprite sheet.
This will contain all the spirites your object, in this case the rocket. Some of these images would be of the rocket smashing into many pieces, fire etc...
Then when your object hits, you play the collision animation. Your method would technically work, but it's overkill. Using a sprite sheet is simple, rather than drawing a massive image, you just draw a portion of the sheet, and to play the animation increment in the X an Y axis of the sheet. This naturally requires the sheet to be layed out even, but it's not too much work.
For some situations, you can simply draw another sprite on top of the original sprite. Alternatively, you can switch between different sprites depending on the state of the object.
I see you have tagged this with XNA, so assume that is your API (though this answer could well be applied to any OpenGL/D3d approach with appropriate calls). If you want to do this in an elegant fashion, I suggest using a temporary RenderState. You would switch to the new RenderState and draw your original background texture, then draw crater sprites over the top (you can modify the AlphaSourceBlend and AlphaDestinationBlend properties of the RenderState to create the subtractive effect you are looking for).
Once you have finished drawing, you can retrieve the RenderState as a texture easily using the GetTexture() function.
Keep in mind that if you are changing the blend modes, your SpriteBatch should be performing in the "immediate" mode (I forget the XNA term, but the one where it doesn't do ordering of sprites for efficiency) else it will be reset unexpectedly.
View this: http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series2D/Adding_craters.php
Slow, but probably fast enough.
public static void Fill(this Texture2D t, Func<int, int, Color> perPixel)
{
var data = new Color[t.Height * t.Width];
for (int y = 0; y < t.Height; y++)
for (int x = 0; x < t.Width; x++)
{
data[x + (y * t.Width)] = perPixel(x, y);
}
t.SetData(data);
}
I was working on something like this on a mobile Java game, a worms/scorched earth clone (actually based on GunBound).
You don't "skip" the pixels in order to leave a crater. You change the pixels in your planet's bitmap, so the crater is now a permanent part of your planet. I assume you know all about bitmaps, blitting transparent, and hit testing.
To create a crater I used a circle-fill algorithm and filled the "explosion area" with the background or transparent color.
So when doing hit-testing you have to do it twice. A bounding-box hit test for speed, then a per-pixel hit test when then bounding boxes overlap.