I would like to know the standard method for resizing my DirectX control. A model is shown in the control, and I want it to be the same size after resize, only more of its environment should be visible.
I managed to do it with resetting the viewport and swapchain buffers, but I could do it another way too (moving the camera), and maybe others I didn't think of. I just don't know which is the "best" way.
Changing the viewport size should only show "more" of the viewing area as a matter of changing the aspect ratio. For instance, if the viewport doubles in width and height, the aspect ratio will be the same, therefore the same image will be shown, just larger.
In contrast, moving the camera will change the amount that is viewed, e.g. If you move the camera back, you will see more. However, this may not be what you are looking for. You are physically moving the camera to another location rather than simply changing the view properties.
What you are probably looking for is to change the camera projection properties, which would likely be done using "PerspectiveFovLH", the input for which is: ("field of view", "aspect ratio", "z near plane", "z far plane"). Widening the field of view (FOV) will allow you to see more of the scene. Changing the aspect ratio will scale that appropriately. Typically the aspect ratio should be the ratio between the screen width and height, and if you want a larger screen to show more overall, scale the FOV by the amount the screen has been re-sized.
Related
Recently I thought: "Let's set the 'resolution' from 16:9 to 16:9(1920x1080)" but i noticed that now all my positioning* code was off, and the size of pictures and text was way too small.
My problem now is, if I should just use the 16:9 aspect ratio or an fixed resolution (I don't know the benefits). But if I shouldn't use the aspect ratio, how to change the fixed resolution when the Project is ready, for example in the settings, without needing to rewrite all my code* and rescale all my images on the Canvas according to the resolution.
*For those of you who don't know what I mean with 'positioning', I mean setting the position of an Image on the Canvas, which obviously needs to be changed because the resolution is different. You could make something that detects your resolution and positions you image based on that, but idk if there is a better solution.
The best way to do this is during positioning ui using procentage also canvas Type which is displayed to resolution.
https://youtu.be/Tys6QWi9RpM
Solution on yt.
The "game" I am trying to create has many buttons and images on the screen at once, and the buttons are designed for the base (what I believe to be 800x600) console size. The buttons and sprites are all in set positions.
The issue I am having is trying to get every image to scale when I do isfullscreen=true. The images stay in their relative position, but I need them to 'scale' based on the the actual size of the window.
While searching for an answer, I have found many that scale individual images or scale them based on the aspect ratio but what I am attempting to do is scale all images, no matter the aspect ratio, depending on the actual size of the XNA window. For example, If I have 3 100x60 sprites and 2 200x90 sprites placed on a 800x600 screen, how would I change the sprites to be the same relative size if the window size were to be changed to 1980x720 without having to manipulate each image?
Thanks
Edit: I've tried using a scale matrix, but that seems to require me setting the EXACT scale for that exact size, meaning I have to create a different scale matrix for each possible window size, which is not what I am trying to achieve.
I've fixed the issue i've been having using a ScaleMatrix, as I was using them incorrectly before.
Before, I was using a matrix of (800, 600) but now (I don't have access to the environment right now so it will have to be in pseudo) I have changed the code so its a variable scale:
(f)XScale = 800 / Viewport.Width
(f)Yscale = 600 / Viewport.Height
Matrix.createScale(XScale, YScale, 1 , 1)
I then passed this to the Spritebatch.Begin. The issue is, if you have something rendered to a triangle (Such as a background), then you may wish to render it in a different spritebatch.Begin as this scale will mess with the triangle.
I have a background rectangle and it applies the scale to it, which puts it off the screen. Its fine if it is something you wish to have scaled, such as a button rectangle.
For some reason, everything I tried that was online about resolution independence doesn't really work the way I would want it to. Most of the solutions suggest a way to get the width and height and then use a class with them, but the result is always a cutoff picture(too big picture) or a picture in the top left corner with smaller height and width than those of the screen.
P.S. The game is in fullscreen, but we tried windowed and it didn't work either.
This is actually a pretty simple fix. Basically, create a RenderTarget object somewhere and do all your drawing to that object, then resize that to the screen.
Use GraphicsDevice.SetRenderTarget(target) to change the render target, then do all your drawing operations, then change it back to the back buffer afterwards by setting it to null. RenderTargets actually derive from Texture2D, so you can use it in as an argument, such as: SpriteBatch.Draw(renderTarget, Viewport.Bounds, Color.White), and this will stretch it to fit the screen.
I am using axWindowsMediaPlayer and when I make the screen full, video is being shown but the player put 2 black block near side of video. I don't want these blocks.
I tried
axWindowsMediaPlayer1.stretchToFit = true;
but that didn't work. Because my video is 800*600 and my screen 1920*1080, the problem might be. Any way to solve this problem programatically? I don't want to resize video.
Thanks in advance.
AxWMPlayer does not support nonuniform stretching. So, you have to either:
- make the WMPlayer of normal desired size, stretch uniformly (StretchToFit=true) and live with the black margins if they show up
- make the WMPlayer oversized in Height or Width (so that it sticks out of the target space), stretch uniformly (StretchToFit=true). Due to the oversized WMPlayer, some of the video will be trucated (displayed outside of the space) but also the black margins will be truncated
Those two ways will mantain aspect ratio.
If you don't need aspect ratio kept, you may apply some ScalingTransform (WPF) or another similar effect to stretch the view afterwards. You will need to calculate coordinates properly, but the fact that WMP always centers the video and that you can read the video dimensions from IWMPMedia helps much.
I do NOT want the system trying to scale my drawing, I want to do it entirely on my own as any attempt to squeeze/stretch the graphics will produce ugly results. The problem is that as the image gets bigger I want to add more detail rather than have it simply scale up.
Right now I'm looking at two sets of stripes. One is black/white, the other is black/white/white. The pen width is set to 1.
When the line is drawn horizontally it's correct. The same logic drawing vertical lines appears to be doing some antialiasing, bleeding the black onto the nearby white. The black/white/white doesn't look as good as the horizontal, the black/white looks more like medium++ gray/medium-- gray.
The same code is generating the coordinates in all cases, the transform logic is simply selecting what offset to apply where as I am only supporting orientations on the cardinals. Since there's no floating point involved I can't be looking at precision issues.
How do I get the system to leave my graphics alone???
(Yeah, I realize this won't work at very high resolution and eventually I'll have to scale up the lines. Over any reasonable on-screen zoom factor this won't matter, for printer use I'll have to play with it and see where I need to scale. The basic problem is that I'm trying to shoehorn things into too few pixels without just making blobs.)
Edit: There is no scaling going on. I'm generating a bitmap the exact size of the target window. All lines are drawn at integer coordinates. The recommendation of setting SmoothingMode to None changes the situation: Now the black/white/white draws as a very clear gray/gray/white and the black/white draws as a solid gray box. Now that this is cleaned up I can see some individual vertical lines that were supposed to be black are actually doing the same thing of drawing as 2-pixel gray bars. It's like all my vertical lines are off by 1/2 pixel--yet every drawing command gets only integers.
Edit again: I've learned more about the problem. The image is being drawn correctly but trashed when displayed to the screen. (Saving it to disk and viewing it on the very same monitor shows it drawn correctly.)
You really should let the system manage it for you. You have described a certain behavior that is specific to the hardware you are using. Given different hardware, the problem may not exist at all, or it may exist horizontally but not vertically, or may only exist at much smaller or much larger resolutions, etc. etc.
The basic problem you described sounds like the vertical lines are being drawn "between" vertical stacks of pixels, which is causing the system to draw an anti-aliased line. The alternative to anti-aliasing the line is to shift it. The problem with that is the lines will "jitter" or "jerk" if the image is moved around, animated, or scaled or transformed in any other way. Generally, jerk is MUCH less desirable than anti-aliasing because it is more distracting.
You should be able to turn off anti-aliasing using the SmoothingMode enum, or you could try to handle positioning yourself. Either way, you are trading anti-aliasing for jittery, jerky rendering during any movement or transformation.
Have a look at System.Drawing.Drawing2d.SmoothingMode. Setting it to 'Default' or 'None' should turn off anti aliasing when doing line drawing. If you're talking about scaling an image without anti aliasing effects, have a look at InterpolationMode. Specifically, you might wish to set it to 'Nearest-Neighbor' which will keep your rectangular blocks perfectly crisp. Note that you will see some odd effects if you scale your image by anything other than whole numbers.
Perhaps you need to align your lines on half-pixel coordinates? A one pixel line drawn at say x = 5 would be drawn on the center of the line, which means it would go from x = 4.5 to x = 5.5. If you want it to go from x = 4 to x = 5 then you'd need to set its coordinate to x = 4.5.
GDI+ has a property: http://msdn.microsoft.com/en-us/library/system.drawing.graphics.pixeloffsetmode.aspx that allows you to control this behavior.
Sounds like you need to change your application to tell the system it is DPI aware so scaling doesn't occur. Here's an article on doing that: http://msdn.microsoft.com/en-us/library/ms701681%28VS.85%29.aspx