Ok so i am following this tutorial Water Reflection XNA and when i adjust code with monogame i cant get final result.
So here is my LoadContent code:
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
texture = Content.Load<Texture2D>("test");
effect = Content.Load<Effect>("LinearFade");
effect.Parameters["Visibility"].SetValue(0.7f);
}
and my Draw code:
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin(SpriteSortMode.Immediate, BlendState.AlphaBlend);
//effect.CurrentTechnique.Passes[0].Apply();
spriteBatch.Draw(texture, new Vector2(texturePos.X, texturePos.Y + texture.Height), null, Color.White * 0.5f, 0f, Vector2.Zero, 1, SpriteEffects.FlipVertically, 0f);
spriteBatch.End();
spriteBatch.Begin();
spriteBatch.Draw(texture, texturePos, Color.White);
spriteBatch.End();
base.Draw(gameTime);
}
and finally my .fx file: LinearFade
So the problem starts when i apply effect. My texture just disappear and if i comment effect part in Draw method i get mirror image with fade (messing with alpha "Color.White * 0.5f") but without fade effect like he have on tutorial from middle of picture to the bottom of picture. I still dont have much experience in monogame and shader but i am learning.
If any1 know how to fix this or how to make it like on tutorial above it would be nice. Btw sry for bad english not my main language.
Ok no need for help i got it after 2 day of thinking i know the answer. The thing is that you need default vertex shader input and output and then shader is working. So if any1 have problem with shaders in monogame first see if you have default vertex input and output. Will put solution code so if some1 doing same tutorial or similer thing so they know what is the problem.
Solution: Working Effect.fx
Related
Above is an example of my problem. I have two alpha masks that are exactly the same, just a circle white gradient with transparent background.
I am drawing to a RenderTexture2D that is rendered above the screen to creating lighting. It clears a semi transparent black color, and then the alpha masks are drawn in the correct position to appear like lights..
On their own it works fine, but if two clash, like the below "torch" against the blue glowing mushrooms, you can see the bounding box transparency is overwriting the already drawn orange glow.
Here is my approach:
This is creating the render target:
RenderTarget2D = new RenderTarget2D(Global.GraphicsDevice, Global.Resolution.X+4, Global.Resolution.Y+4);
SpriteBatch = new SpriteBatch(Global.GraphicsDevice);
This is drawing to the render target:
private void UpdateRenderTarget()
{
Global.GraphicsDevice.SetRenderTarget(RenderTarget2D);
Global.GraphicsDevice.Clear(ClearColor);
// Draw textures
float i = 0;
foreach (DrawableTexture item in DrawableTextures)
{
i += 0.1f;
item.Update?.Invoke(item);
SpriteBatch.Begin(SpriteSortMode.Immediate, item.Blend,
SamplerState.PointClamp, DepthStencilState.Default,
RasterizerState.CullNone);
SpriteBatch.Draw(
item.Texture,
(item.Position - Position) + (item.Texture.Size() / 2 * (1 - item.Scale)),
null,
item.Color,
0,
Vector2.Zero,
item.Scale,
SpriteEffects.None,
i
);
SpriteBatch.End();
}
Global.GraphicsDevice.SetRenderTarget(null);
}
I have heard about depth stencils etc.. and I feel like I have tried so many combinations of things but I am still getting the issue. I haven't had any troubles with this while building all the other graphics in my game.
Any help is greatly appreciated thanks! :)
Ah, this turned out to be a problem with the BlendState itself rather than the SpriteBatch. I had created a custom BlendState "Multiply" which I picked up online that was causing the issue.
"whats causing" the problem was the real question here.
This was the solution to get my effect without "overlapping":
public static BlendState Lighting = new BlendState
{
ColorSourceBlend = Blend.One,
ColorDestinationBlend = Blend.One,
AlphaSourceBlend = Blend.Zero,
AlphaDestinationBlend = Blend.InverseSourceColor
};
This allows the textures to overlap, and also "subtracts" from the "darkness" layer. It would be easier to see if the darkness was more opaque.
I have answered this just incase some other fool mistakes a blend state problem with the sprite batch itself.
I'm trying to draw a bullet in Monogame with a high velocity. When I draw it for about 400px/sec "Which is quite slow" but around 1500px/sec it starts "duplicating" or "ghosting" the Texture. I am fairly new to Monogame and do not have alot of knowledge on Graphics.
How can I move an object with High Velocity without creating a "ghost" effect ?
SpriteBatch Begin :
sb.Begin(SpriteSortMode.Deferred, BlendState.AlphaBlend, SamplerState.LinearWrap, DepthStencilState.None, RasterizerState.CullNone,
null, Global.Camera.GetViewTransformationMatrix());
Draw Method :
public override void Draw(SpriteBatch sb)
{
Vector2 origin = new Vector2(source.Width / 2, source.Height / 2);
Rectangle tRect = Bounds;
sb.Draw(
texture: TDTGame.GameAssets.Texture,
destinationRectangle: tRect,
sourceRectangle: source,
rotation: MathHelper.ToRadians(Rotation - 270f), //Set rotation to forward of the texture.
color: Color.White,
origin: origin,
layerDepth: 1f
);
}
Edit:
Youtube Link : here
Movement of the bullet :
float traveledDistance;
public override void Update(GameTime gt)
{
float deltaTime = (float)gt.ElapsedGameTime.TotalSeconds;
traveledDistance += Speed * deltaTime;
Position += Forward * Speed * deltaTime;
if (traveledDistance > Range)
{
Destroy();
}
}
This is likely an artifact of low frame rate. The higher the frame rate, the less your brain will register the fact that the bullet's "movement" is simply drawing the same image in multiple and changing locations over time :)
As stated the traces are probably in your eyes, not on the screen. If you want to overcome this effect, you may want to skip some frames (maybe completely remove the bullet from screen or at least skip movement).
i have developed cocos 2dx game in which i am running animation in the Sprite in which i want to get the current texture name for that i have tried following code:
CCSpriteFrame *frameN = fisherManBoat->displayFrame();
frameName = frameN->_textureFilename;
But it gives me error that textureFilename is protected so how can i resolve it ? If it doesn't work then what else i can try? Because there is a button on the screen on which i tap and animation runs, i want to make it smooth. So, that if animation is in between on taping again it doesn't starts from again but from its current point.
if you want to access the _textureFilename variable the you need to modify the CCSpriteFrame.h file.
First you need to find this code in CCSpriteFrame.h file
protected:
Vec2 _offset;
Size _originalSize;
Rect _rectInPixels;
bool _rotated;
Rect _rect;
Vec2 _offsetInPixels;
Size _originalSizeInPixels;
Texture2D *_texture;
std::string _textureFilename;
PolygonInfo _polygonInfo;
And cut below line from this code
std::string _textureFilename;
now you have to paste it on top of CCSpriteFrame.h file where Public Scope is define.
class CC_DLL SpriteFrame : public Ref, public Clonable
{
public:
std::string _textureFilename;
I hope it will help you. Thanks.
I'm using WebCamTexture to get input from the camera (iOS&Android). However, since this is raw input, the rotation is wrong when rendered to a texture. I read around a lot, and found this (look at the bottom): WebCamTexture rotated and flipped on iPhone
His code (but with test-values):
Quaternion rotation = Quaternion.Euler(45f, 30f, 90f);
Matrix4x4 rotationMatrix = Matrix4x4.TRS(Vector3.zero, rotation, new Vector3(1, 1, 1));
material.SetMatrix("_Rotation", rotationMatrix);
But whatever value I use, nothing happens (neither in the editor or on devices)...
Thanks!
Edit
After some intense testing, I found that material.SetMatrix, SetFloat, SetWhatever has NO effect (not setting the value) unless it's declared inside the "Properties"-block. Looking at unity:s own example, this should't have to (and can't) be done for a matrix (can't be declared inside Properties, only inside the CGProgram). So... How do you set a matrix then? Or what else am I doing wrong?
You should be using: WebCamTexture.videoRotationAngle
its designed to solve exactly this problem, read more about this here.
Example code:
using UnityEngine;
using System.Collections;
public class ExampleClass : MonoBehaviour {
public WebCamTexture webcamTexture;
public Quaternion baseRotation;
void Start() {
webcamTexture = new WebCamTexture();
renderer.material.mainTexture = webcamTexture;
baseRotation = transform.rotation;
webcamTexture.Play();
}
void Update() {
transform.rotation = baseRotation * Quaternion.AngleAxis(webcamTexture.videoRotationAngle, Vector3.up);
}
}
Just rotate the camera to 90 degrees along the z axis (the camera is which is rendering the webcamtexture gameobject).
I want to write a very simple Effect for a DirectX program which uses the ID3DXSprite interface to draw a 2D-Hud. In XNA I simply called
spriteBatch.Begin(SpriteBlendMode.AlphaBlend, SpriteSortMode.Immediate, SaveStateMode.None);
effect.Begin();
effect.CurrentTechnique.Passes[0].Begin();
spriteBatch.Draw(texture, new Rectangle(0, 0, 300, 300), Color.White);
effect.CurrentTechnique.Passes[0].End();
effect.End();
spriteBatch.End();
But in C++, nearly the same code doesnt work
pSprite->Begin(D3DXSPRITE_ALPHABLEND | D3DXSPRITE_DONOTSAVESTATE | D3DXSPRITE_SORT_TEXTURE);
anEffect->SetTechnique(technique);
anEffect->Begin(&passes, 0);
anEffect->BeginPass(0);
pSprite->Draw(pTexture, NULL, NULL, &position, 0xFFFFFFFF);
anEffect->EndPass();
anEffect->End();
pSprite->End();
NOTE: The effect is loaded correctly!
Well, first of all the XNA code you have is for XNA 3.1, and it's wrong. This blog post explains how to do it for both XNA 3.1 and 4.0 (the API changes in between).
In XNA 3.1, when using SpriteSortMode.Immediate, SpriteBatch will set up its shaders and other device state in the Begin call, instead of in the End call. This gives you the opportunity to replace parts of the device state before drawing actually takes place (in Draw or End, depending on when it flushes). And then you are supposed to End your effect after you End the sprite batch (so everything gets drawn first).
Now, in DirectX, I would suggest that the same incorrect ordering of your End calls is to blame. Specifically refer to this part of the documentation for the second parameter to ID3DXEffect::Begin
determines if state modified by an effect is saved and restored. The default value 0 specifies that ID3DXEffect::Begin and ID3DXEffect::End will save and restore all state modified by the effect
The upshot is that, when you End the effect, it is resetting the device back to normal sprite drawing, before you call End on the ID3DXSprite, which is what is actually sending your sprite batch to be drawn.
I would guess that the reason your incorrectly-ordered code works on XNA is that XNA is probably doing the equivalent of passing D3DXFX_DONOTSAVESTATE, when beginning the effect, under the hood.
Usage of Sprite with HLSL Effect: (for C++ Game Developers)
Below is the sample code which explains how sprite draw can work with HLSL effect files
Pseudo Code:
ID3DXEffect* g_pEffect = NULL; // D3DX effect interface
void loadTextureEffect() {
D3DXCreateTextureFromFile(gD3dDevice,L"image.png",&gTextureBackdrop);
DWORD dwShaderFlags = D3DXFX_NOT_CLONEABLE;
D3DXCreateEffectFromFile( gD3dDevice, "shader.fx", NULL, NULL, dwShaderFlags,
NULL, &g_pEffect, NULL );
}
void Render()
{
unsigned int passes;
gD3dDevice->Clear(0, 0, D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER, 0x00000000, 1.0f, 0);
gD3dDevice->BeginScene();
gSprite->Begin(0);
g_pEffect->SetTechnique("PostProcess");
g_pEffect->SetTexture( "Tex0", gTextureBackdrop );
float blurFactor = 25;
g_pEffect->SetValue("TextureBlur",&blurFactor ,sizeof(float));
g_pEffect->Begin(&passes, 0);
for(unsigned int pass = 0; pass < passes; ++pass)
{
g_pEffect->BeginPass(pass);
D3DXVECTOR3 spritePos(0.0f, 0.0f, 0.0f);
gD3dDevice->SetTexture(0,gTextureBackdrop);
gSprite->Draw(gTextureBackdrop, 0, 0, &spritePos, 0xffffffff);
gSprite->End();
g_pEffect->CommitChanges();
g_pEffect->EndPass();
}
g_pEffect->End();
gD3dDevice->EndScene();
gD3dDevice->Present(NULL,NULL,NULL,NULL);
}