Stretching a Sprite - sprite

First post, first year programmer so go easy please.
When drawing a sprite in monogame, does anybody know how to make it stretch into the full screen?
For example I have my start screen appear but it doesnt stretch into the full screen (cause i have my window maximized when it opens). I've got "spriteBatch.Draw(startScreen, Vector2.Zero, null, Color.White);"
the null represents the rectangle property. does anybdoy know a word to replace null so that will stretch it?
This is in my load content for the texture:
startScreen = Content.Load<Texture2D>("Images/startGameSplash");
Then this is where I call it in my Draw Method:
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
switch (gameState)
{
case GameState.StartScreen:
//draw the start screen
spriteBatch.Begin();
spriteBatch.Draw(startScreen, Vector2.Zero, null, Color.White);
//Drawing each rocket with another foreach
spriteBatch.End();
break;
case GameState.Running:
spriteBatch.Begin();
tank.Draw(spriteBatch);
foreach (BaseRocket shot in rocket) {
shot.Draw(spriteBatch);
}
spriteBatch.End();
break;
case GameState.EndScreen:
spriteBatch.Begin();
spriteBatch.Draw(endScreen, Vector2.Zero, null, Color.White);
spriteBatch.End();
break;
default:
break;
}
base.Draw(gameTime);
}
}
}
Thanks,

From the source code / documentation of SpriteBatch class of MonoGame, there is a Draw function which accepts size as 2nd parameter:
public void Draw (Texture2D texture, Rectangle rectangle, Color color)
Assign the screen size rectangle to the parameter, and your sprite should fill the screen.

Related

How do I change the background color of a tabbed page in Xamarin iOS?

I need to change the background color of the currently tabbed page in my UITabBarController. I've searched through every stackoverflow post I could find but nothing worked for me. I thought there would be something like UITabBar.Appearance.SelectedImageTintColor, just for the background color but it doesn't seem so.
For example, I want to change the color of that part when I am on the right tab:
Does someone know how to do that?
You could invoked the following code in your UITabBarController
public xxxTabBarController()
{
//...set ViewControllers
this.TabBar.BarTintColor = UIColor.Red;
}
Update
//3.0 here is if you have three child page in tab , set it as the current value in your project
//
var size = new CGSize(TabBar.Frame.Width / 3.0, IsFullScreen());
this.TabBar.SelectionIndicatorImage = ImageWithColor(size,UIColor.Green);
double IsFullScreen()
{
double height = 64;
if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
{
if (UIApplication.SharedApplication.Delegate.GetWindow().SafeAreaInsets.Bottom > 0.0)
{
height = 84;
}
}
return height;
}
UIImage ImageWithColor(CGSize size, UIColor color)
{
var rect = new CGRect(0, 0, size.Width, size.Height);
UIGraphics.BeginImageContextWithOptions(size, false, 0);
CGContext context = UIGraphics.GetCurrentContext();
context.SetFillColor(color.CGColor);
context.FillRect(rect);
UIImage image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return image;
}
The trick is to use the SelectionIndicatorImage Property of the UITabBar and generate a completely filled image with your desired color using the following method:
private UIImage ImageWithColor(CGSize size)
{
CGRect rect = new CGRect(0, 0, size.Width, size.Height);
UIGraphics.BeginImageContext(size);
using (CGContext context = UIGraphics.GetCurrentContext())
{
context.SetFillColor(UIColor.Green); //change color if necessary
context.FillRect(rect);
}
UIImage image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();
return image;
}
To initialize everything we override ViewWillLayoutSubviews() like this:
public override void ViewWillLayoutSubviews()
{
base.ViewWillLayoutSubviews();
// The tabbar height will always be 49 unless we force it to reevaluate it's size on runtime ...
myTabBar.InvalidateIntrinsicContentSize();
double height = myTabBar.Frame.Height;
CGSize size = new CGSize(new nfloat(myTabBar.Frame.Width / myTabBar.Items.Length, height));
// Now get our all-green image...
UIImage image = ImageWithColor(size);
// And set it as the selection indicator
myTabBar.SelectionIndicatorImage = image;
}
As mentioned in this article (google translating it step by step when necessary lol) calling InvalidateIntrinsicContentSize() will force the UITabBar to reevaluate it's size and will get you the actual runtime height of the tab bar (instead of the constant 49 height value from XCode).

Creating a horizontal separator in a vertical UIStackView

I have a vertical stack view that contains a number of horizontal stack views. How can I create a 1px separator line between the horizontal stackviews?
You can create a Separator View:
class SeparatorView: UIView {
init() {
super.init(frame: .zero)
setUp()
}
override init(frame: CGRect) {
super.init(frame: frame)
setUp()
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func setUp() {
backgroundColor = .gray
}
override var intrinsicContentSize: CGSize {
return CGSize(width: UIView.noIntrinsicMetric, height:0.5)
}
}
And add it to your StackView in between the horizontal views:
stackView.addArrangedSubview(horizontalView)
stackView.addArrangedSubview(SeparatorView())
This will create a small gray line that separates the views.
just add in a UIView with a 1-2px width and the same height as each of the horizontal stack views in between the two middle most controls in the horizontal stack view. Assuming that there is no top or bottom spacing it would give the impression of a vertical line without breaks, or if you don't mind breaks in the vertical line then don't worry about removing top or bottom spacing.
OR
You could leverage the fact that UIStackView can take subviews, and just work out the centre x, and with a y of 0, add in a 2px wide UIView as a subview of the UIStackView.
Something like:
UIStackView sv = new UIStackView();
UIView ViewLine = new UIView();
ViewLine.Frame = new CGRect(CentreX, 0 , 2f , heightofstackview );
sv.AddSubview();

Color of texture skybox unity

I'm working with google cardboard in unity.
In my main scene I have a skybox with an image as texture.
How can I get the color of the pixel I'm looking?
The skybox is an element of mainCamera, that is child of "Head".
I put also GvrReticle as child of head; is it useful for my purpose?
Thanks
Basically you wait for the end of the frame so that the camera has rendered. Then you read the rendered data into a texture and get the center pixel.
edit Be aware that if you have a UI element rendered in the center it will show the UI element color not the color behind.
private Texture2D tex;
public Color center;
void Awake()
{
StartCoroutine(GetCenterPixel());
}
private void CreateTexture()
{
tex = new Texture2D(1, 1, TextureFormat.RGB24, false);
}
private IEnumerator GetCenterPixel()
{
CreateTexture();
while (true)
{
yield return new WaitForEndOfFrame();
tex.ReadPixels(new Rect(Screen.width / 2f, Screen.height / 2f, 1, 1), 0, 0);
tex.Apply();
center = tex.GetPixel(0,0);
}
}

Adding CSliderCtrl in CStatusBar in MFC application

I am trying to add to CSliderCtrl in CStatusBar. For this
- Created CSliderCtrl in CMainFrame class
- In CMainFrame::OnCreate() added code for creating statusbar and slider bar control as
bStatus = m_ZoomSlider.Create(
WS_CHILD | WS_VISIBLE,
CRect(0, 0, 100, 30),
&m_StatusBar,
56666);
Things are working fine.
Now I want this slider to be on the right side of the status bar. For this I've added a INDICATOR in the status bar and I am trying to get the rect of this indicator and placing the slider over that rect.
CRect rectSlider;
m_StatusBar.GetItemRect(1, &rectSlider);
bStatus = m_ZoomSlider.Create(
WS_CHILD | WS_VISIBLE,
rectSlider,
&m_StatusBar,
56666);
Here the rectSlider is having negative value, causing the slider to be invisible.
I need to know Is this the correct way for doing this. Any suggestion for advice will be very helpful.
I am using Visual Studio 2005.
You should be using GetRect rather than GetItemRect, I think
The slider control cannot be displayed because its Z-order is not correct. So override on resize to reposition the slider properly. &CWnd::wndTop means placing the window at the top of the Z-order
Firstly, define CSliderCtrl *m_pZoomSlider in MainFrame.h
The following code used the lazy initialization pattern: initialize when required, free the allocated memory when frame is being destroyed.
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
...
ON_WM_SIZE()
END_MESSAGE_MAP()
void CMainFrame::SetSliderPosition(int pos)
{
if (!m_pZoomSlider) {
CRect rectSlider;
m_wndStatusBar.GetItemRect(1, &rectSlider);
rectSlider.DeflateRect(1, 1); // 1 pixel border...
m_pZoomSlider = new CSliderCtrl();
m_pZoomSlider->Create(WS_CHILD | WS_VISIBLE, rectSlider, &m_wndStatusBar, ID_INDICATOR_SCALE_SLIDER);
m_pZoomSlider->SetRange(1, 100);
}
RECT rc;
m_wndStatusBar.GetItemRect(pos, &rc);
// Reposition the slider control correctly!
m_pZoomSlider->SetWindowPos(&CWnd::wndTop, rc.left, rc.top, rc.right - rc.left, rc.bottom - rc.top, 0);
}
void CMainFrame::OnSize(UINT nType, int cx, int cy)
{
CFrameWnd::OnSize(nType, cx, cy);
SetSliderPosition(1); //index of indicator of status bar
}
BOOL CMainFrame::DestroyWindow()
{
if (m_pZoomSlider) {
m_pZoomSlider->DestroyWindow();
delete m_pZoomSlider;
}
return CFrameWnd::DestroyWindow();
}

C#/XNA/HLSL - Applying a pixel shader on 2D sprites affects the other sprites on the same render target

Background information
I have just started learning HLSL and decided to test what I have learned from the Internet by writing a simple 2D XNA 4.0 bullet-hell game.
I have written a pixel shader in order to change the color of bullets.
Here is the idea: the original texture of the bullet is mainly black, white and red. With the help of my pixel shader, bullets can be much more colorful.
But, I'm not sure how and when the shader is applied on spriteBatch in XNA 4.0, and when it ends. This may be the cause of problem.
There were pass.begin() and pass.end() in XNA 3.x, but pass.apply() in XNA 4.0 confuses me.
In addition, it is the first time for me to use renderTarget. It may cause problems.
Symptom
It works, but only if there are bullets of the same color in the bullet list.
If bullets of different colors are rendered, it produces wrong colors.
It seems that the pixel shader is not applied on the bullet texture, but applied on the renderTarget, which contains all the rendered bullets.
For an example:
Here I have some red bullets and blue bullets. The last created bullet is a blue one. It seems that the pixel shader have added blue color on the red ones, making them to be blue-violet.
If I continuously create bullets, the red bullets will appear to be switching between red and blue-violet. (I believe that the blue ones are also switching, but not obvious.)
Code
Since I am new to HLSL, I don't really know what I have to provide.
Here are all the things that I believe or don't know if they are related to the problem.
C# - Enemy bullet (or just Bullet):
protected SpriteBatch spriteBatch;
protected Texture2D texture;
protected Effect colorEffect;
protected Color bulletColor;
... // And some unrelated variables
public EnemyBullet(SpriteBatch spriteBatch, Texture2D texture, Effect colorEffect, BulletType bulletType, (and other data, like velocity)
{
this.spriteBatch = spriteBatch;
this.texture = texture;
this.colorEffect = colorEffect;
if(bulletType == BulletType.ARROW_S)
{
bulletColor = Color.Red; // The bullet will be either red
}
else
{
bulletColor = Color.Blue; // or blue.
}
}
public void Update()
{
... // Update positions and other properties, but not the color.
}
public void Draw()
{
colorEffect.Parameters["DestColor"].SetValue(bulletColor.ToVector4());
int l = colorEffect.CurrentTechnique.Passes.Count();
for (int i = 0; i < l; i++)
{
colorEffect.CurrentTechnique.Passes[i].Apply();
spriteBatch.Draw(texture, Position, sourceRectangle, Color.White, (float)Math.PI - rotation_randian, origin, Scale, SpriteEffects.None, 0.0f);
}
}
C# - Bullet manager:
private Texture2D bulletTexture;
private List<EnemyBullet> enemyBullets;
private const int ENEMY_BULLET_CAPACITY = 10000;
private RenderTarget2D bulletsRenderTarget;
private Effect colorEffect;
...
public EnemyBulletManager()
{
enemyBullets = new List<EnemyBullet>(ENEMY_BULLET_CAPACITY);
}
public void LoadContent(ContentManager content, SpriteBatch spriteBatch)
{
bulletTexture = content.Load<Texture2D>(#"Textures\arrow_red2");
bulletsRenderTarget = new RenderTarget2D(spriteBatch.GraphicsDevice, spriteBatch.GraphicsDevice.PresentationParameters.BackBufferWidth, spriteBatch.GraphicsDevice.PresentationParameters.BackBufferHeight, false, SurfaceFormat.Color, DepthFormat.None);
colorEffect = content.Load<Effect>(#"Effects\ColorTransform");
colorEffect.Parameters["ColorMap"].SetValue(bulletTexture);
}
public void Update()
{
int l = enemyBullets.Count();
for (int i = 0; i < l; i++)
{
if (enemyBullets[i].IsAlive)
{
enemyBullets[i].Update();
}
else
{
enemyBullets.RemoveAt(i);
i--;
l--;
}
}
}
// This function is called before Draw()
public void PreDraw()
{
// spriteBatch.Begin() is called outside this class, for reference:
// spriteBatch.Begin(SpriteSortMode.Immediate, null);
spriteBatch.GraphicsDevice.SetRenderTarget(bulletsRenderTarget);
spriteBatch.GraphicsDevice.Clear(Color.Transparent);
int l = enemyBullets.Count();
for (int i = 0; i < l; i++)
{
if (enemyBullets[i].IsAlive)
{
enemyBullets[i].Draw();
}
}
spriteBatch.GraphicsDevice.SetRenderTarget(null);
}
public void Draw()
{
// Before this function is called,
// GraphicsDevice.Clear(Color.Black);
// is called outside.
spriteBatch.Draw(bulletsRenderTarget, Vector2.Zero, Color.White);
// spriteBatch.End();
}
// This function will be responsible for creating new bullets.
public EnemyBullet CreateBullet(EnemyBullet.BulletType bulletType, ...)
{
EnemyBullet eb = new EnemyBullet(spriteBatch, bulletTexture, colorEffect, bulletType, ...);
enemyBullets.Add(eb);
return eb;
}
HLSL - Effects\ColorTransform.fx
float4 DestColor;
texture2D ColorMap;
sampler2D ColorMapSampler = sampler_state
{
Texture = <ColorMap>;
};
struct PixelShaderInput
{
float2 TexCoord : TEXCOORD0;
};
float4 PixelShaderFunction(PixelShaderInput input) : COLOR0
{
float4 srcRGBA = tex2D(ColorMapSampler, input.TexCoord);
float fmax = max(srcRGBA.r, max(srcRGBA.g, srcRGBA.b));
float fmin = min(srcRGBA.r, min(srcRGBA.g, srcRGBA.b));
float delta = fmax - fmin;
float4 originalDestColor = float4(1, 0, 0, 1);
float4 deltaDestColor = originalDestColor - DestColor;
float4 finalRGBA = srcRGBA - (deltaDestColor * delta);
return finalRGBA;
}
technique Technique1
{
pass ColorTransform
{
PixelShader = compile ps_2_0 PixelShaderFunction();
}
}
I would be appreciate if anyone can help solving the problem. (Or optimizing my shader. I really know very little about HLSL.)
In XNA 4 you should pass the effect directly to the SpriteBatch, as explained on Shawn Hargreaves' Blog.
That said, it seems to me like the problem is, that after rendering your bullets to bulletsRenderTarget, you then draw that RenderTarget using the same spriteBatch with the last effect still in action. That would explain why the entire image is painted blue.
A solution would be to use two Begin()/End() passes of SpriteBatch, one with the effect and the other without. Or just don't use a separate RenderTarget to begin with, which seems pointless in this case.
I'm also very much a beginner with pixel shaders so, just my 2c.

Resources