Create a polygon filled with a tiled image in c# - c#

I'm creating an application which visualises a picture frame as the user designs it. To create the frame I am drawing 4 polygons which represent the physical bits of wood and using a TextureBrush to fill it.
This works perfectly well for the left and top edges. However, for the bottom and right edges this method isn't working. It appears to me that the TextureBrush is tiling from the point (0,0) on the image and not within the polygon I've drawn. As a result, the tile doesn't line up with the polygon. By adjusting the size of the image I can get the tile to line up perfectly.
How do I create an arbitrarily positioned polygon and fill it with a tiled image, starting from the point (0,0) within the polygon, not the canvas?
I'm not attached to FillPolygon and TextureBrush if there is a better solution.
Example

I've just found the answer. I was playing with adding a BoundingBox to the TextureBrush constructor but I kept getting OutOfMemory exceptions and thought it was me not understanding. Turns out it's a bug in the .NET framework
http://connect.microsoft.com/VisualStudio/feedback/details/90973/texturebrush-constructor-throws-out-of-memory-exception-when-providing-the-bounding-rectangle
The work around is to use a transformation to move the texture
var brush = new TextureBrush(new Bitmap(imagefile));
Matrix mtx = brush.Transform;
mtx.Translate(xoffset, 0);
brush.Transform = mtx;

Related

Why texture appear on Bottom Left with Frame Buffer Object

I'm trying to render to texture using FBO using OpenTK in C#.
When I try to render, everything show up and just fine except the texture is shown on bottom-left corner, I'm expecting it shown on the top left corner.
Also the Texture appear flipped in Y axis, So I need to modify the Texture Matrix after binding the Texture Target.
If I just bind my texture and draw the vertices, the sprite will appear on top-left corner.
The codes I use is looks exactly same from the official documentation.
I got 2 questions:
1. Am I doing it right to make the target texture show up properly by modifying the Texture Matrix?
2. How to make the texture target appear on top left corner?
Thanks in advance!
Actually Origin is at Bottom Left , therefore the FBO is getting displayed in the Bottom Left.
In the normal images , the texture space 0,0 is at top therefore you don't see it flipped.
So you have to add the texture matrix to make the space same.
When I try to render, everything show up and just fine except the texture is shown on bottom-left corner,
Yes. In OpenGL the origin (0,0) of 2D images (the viewport, textures, render buffers) is in the lower left.
I'm expecting it shown on the top left corner.
Why? The origin (as far as OpenGL is concerned) is in the lower left. Why'd you expect it in the top?
I encountered similar problems when the first time I tried FBO, so here my answer:
Although there several ways to workaround against this Upside down problem, Modifying Texture Matrix isn't bad idea at all. Sometimes modifying Texture matrix could be handy in certain situation, e.g: Use non normalized texture coordinate, So you can add such features to your bind texture function.
It's seems projection / viewport issue, if you are sure that the normal sprite appear on top-left coordinate, try to re-setup your projection / view / camera before unbind the FBO handle.

Scrolling texture in cycle

I'm using C# and XNA and I would like to make a scrolling background in my game.
I'm trying to figure out what the best way to implement a scrolling texture that moves in some direction indefinitely. Let's say a space background with stars. So, when ship moves do does the texture, but in opposite direction. Kinda like in "tiling" mode.
My only guess so far is to render two textures which are, let's say moving left, and then just make the most left one jump to right when it's beyond visibility or something similar to this.
So, I was wondering is there some simple way to do it in XNA, maybe some render mode, or is the way I described it is good enough? I just don't want to overcomplicate things. I obviously tried to google first, but found pretty much nothing, but it is strange considering that many games use similar techniques too.
Theory
A scrolling background image is easy to implement with the XNA SpriteBatch class. There are several overloads of the Draw method which let the caller specify a source rectangle. This source rectangle defines the section of the texture that is drawn to the specified destination rectangle on screen:
Changing the position of the source rectangle will change the section of the texture displayed in the destination rectangle.
In order to have the sprite cover the whole screen use the following destination rectangle:
var destination = new Rectangle(0, 0, screenWidth, screenHeight);
If the whole texture should be displayed use the following destination rectangle:
var source = new Rectangle(0, 0, textureWidth, textureHeight);
Than all you have to do is animate the source rectangle's X and Y coordinates and you are done.
Well, almost done. The texture should start again even if the source rectangle moves out of the texture area. To do that you have to set a SamplerState that uses texture wrap. Fortunately the Begin method of the SpriteBatch allows the usage of a custom SamplerState. You can use one of the following:
// Either one of the three is fine, the only difference is the filter quality
SamplerState sampler;
sampler = SamplerState.PointWrap;
sampler = SamplerState.LinearWrap;
sampler = SamplerState.AnisotropicWrap;
Example
// Begin drawing with the default states
// Except the SamplerState should be set to PointWrap, LinearWrap or AnisotropicWrap
spriteBatch.Begin(
SpriteSortMode.Deferred,
BlendState.Opaque,
SamplerState.AnisotropicWrap, // Make the texture wrap
DepthStencilState.Default,
RasterizerState.CullCounterClockwise
);
// Rectangle over the whole game screen
var screenArea = new Rectangle(0, 0, 800, 600);
// Calculate the current offset of the texture
// For this example I use the game time
var offset = (int)gameTime.TotalGameTime.TotalMilliseconds;
// Offset increases over time, so the texture moves from the bottom to the top of the screen
var destination = new Rectangle(0, offset, texture.Width, texture.Height);
// Draw the texture
spriteBatch.Draw(
texture,
screenArea,
destination,
Color.White
);
Microsoft has a XNA tutorial that does exactly this, you can grab the source code and read up on the actual programming logic behind a scrolling background. Bonus points they do parallax scrolling for a nice effect.
Link: http://xbox.create.msdn.com/en-US/education/tutorial/2dgame/getting_started

How do I create an image and save it for later to draw as texture in XNA?

In my game I need to draw a circle made of squares the sizes of a game tile (circle is made of squares). I could just draw monochrome square textures in form of a jagged circle each frame, but it consumes a significant amount of resources. What I'd like to do is to draw it somewhere in the memory just once and save to draw each frame after that.
I could simply draw said circle myself and use it as a ready texture, but my circle is not always the same. It has different size throughout the game (and it's not really a circle half of the time, but I've got the algo that says where to draw), so it has to be drawn programmatically.
First you render the circle to a custom RenderTarget2D. You can set a custom render target like this:
GraphicsDevice.SetRenderTarget(renderTarget);
After rendering your circle to the render target cast it to a Texture2D like this:
texture = (Texture2D)renderTarget;
Read more: http://www.riemers.net/eng/Tutorials/XNA/Csharp/Series3/Render_to_texture.php

XNA Rotation Help(Interesting...)

Hello Stack Overflow users, I have a fun problem that I have in my XNA Game.
So basically I have an asteroid, 80x80, and I set the origin as imageW / 2, imageH / 2 (If order would matter, it wouldn't, the asteroid is a square).
Here is an image, explaining the problem! Visualization FTW :D
http://i.imgur.com/dsawS.png
So, any ideas on what is causing this? I spend 1 hour, I looked at examples, I found out it is supposed to rotate like this:
http://www.riemers.net/images/Tutorials/XNA/Csharp/Series2D/rotation.jpg
But it's not.
Here is a code sample. I have a object named Drawable that has properties which hold the vector position, etc.
Vector2 asteroidOrigin = new Vector2(asteroidImgs[asteroid.asteroidType].Width / 2, asteroidImgs[asteroid.asteroidType].Height / 2);
drawableList.Add(new Drawable(asteroidImgs[asteroid.asteroidType], asteroid.asteroidPos, asteroid.angle, asteroidOrigin));
Here is the Draw Method:
foreach (Drawable drawable in renderManager.getRenderList)
{
spriteBatch.Draw(drawable.image, drawable.position, drawable.sourceRectangle, drawable.tint, drawable.angle, drawable.origin, drawable.imageScale, drawable.spriteEffects, drawable.depth);
}
And yes, the Drawable Class has multiple constructors and they assign default values.
When you define an Origin in SpriteBatch.Draw, you are defining the new point on your texture which will draw at the Position argument. Obviously this affects translation as well as your desired rotation. When you set the origin to the center of the image, the image is translated so that the center is at your Position, then rotated around that point. When you set the origin to Vector2.Zero, the translation is not changed, but the image rotates around its top left corner.
The solution is to either redefine what you mean as "Position" for sprites to be where the CENTER of the image draws on screen (I recommend this, makes things nice) or perform a bit of work before drawing by adding the Origin to the Position before calling Draw.
I, again, recommend the first solution, because then when you want to draw a circle in the center of the screen you can just set its position to be the center of the screen and be done. You won't need to take its size into account. And so on.

Rotating part of an image in 3D space

Here's the setup: This is for an ecommerce art site where some paintings are canvas transfers. The painting wraps around the sides and top and bottom of the canvas. We have high-res images of the entire painting, but what we want to display is a quasi-3D representation of the image in which you can see how the sides of the painting wrap around the canvas. Here's a rough sketch of what I'm talking about:
My question is, how can I rotate an image in 3D space? The approach I think I'd like to take, is to cut off a portion of the top and side of the image, and rotate then in 3D and then stich it back on to the top and side to give it the 3D look. How do I go about about doing that? It can be done using any .Net technology (GDI+, WPF etc.).
In WPF using the ViewPort3D class you can create a cuboid which is 8x5x1 units. Create the image as a texture and then apply the texture to the front face (8x5) and the side faces (5x1) and the top and bottom faces (8x1) using texture coordinates. The front face coordinates should be: (1/9, 1/6), (8/9, 1/6), (1/9, 5/6) and (8/9, 5/6) for the front face, and from the nearest edge to those coordinates for the sides, e.g. for the left side: (0, 1/6), (1/9, 1/6), (0, 5/6) and (1/9, 5/6) for the left side.
Edit:
If you then want to be able to perform rotations on the 3D canvas model you can follow the advice here:
How can I do 3D transformation in WPF?
It looks like you're not needing to do real 3D, but only needing to fake it.
Chop off four strips along the top, bottom, left and right of the image. Toss the bottom and right (going by your sketch in the question). Scale and shear the strips (I'm not expert enough at .net/wpf to know how, but it can do it). The top would be scaled vertically by a factor of 0.5 (a guess - choose to fit the desired final 3D-looking image) and sheared horizontally. The result is composited onto the output image as the top side of the canvas. The left strip would be scaled horizontally and sheared vertically.
If the end user is to view the 3D canvas from different angles interactively, this method is probably faster than rendering an honest 3D model, which would have to do texture mapping and rasterizing the model into a final image, which amounts to doing the same math. The fun part is figuring out how to adjust the scaling and shearing parameters.
This page might be educational: http://www.idomaths.com/linear_transformation.php
and this could be useful reference http://en.csharp-online.net/GDIplus_Graphics_Transformation%E2%80%94Image_Transformation
I dont have any experience in this kind of stuff. But when i saw this question, the first thing comes to my mind is the funny Unicornify for SO.
In this making of article by balpha, he explained how the 2d unicorn sphere is rotated in 3d space.
But the code is written in python. If you are interested, you can take a look into that. But am not exactly sure this would help you.
The brute force approach (which might be the easiest approach), is to map the u,v texture coordinates for each of the three faces, onto three billboards representing three sides of the canvas (a billboard is just two triangles that make a rectangle). Then, rotate the whole canvas (all three billboards) using matrix transforms. Tada!
Alternately, you can move the 3-space camera position with a transform, rather than the canvas. Six of one, half the other - as they say.

Categories

Resources