[XNA]Drawing a simple transparent plane - xna

I'm working with XNA and a have a problem.
A basic problem, but argh !!!
I want to draw a ocean, BASIC ocean, just a plane, blue and transparent.
just a plane.
I have try with Vertex, with models and textures.
How tha alpha channel work in XNA ? StencilState, DepthBuffer, nothing would work.
Can you explain how to do this ?
Use VertexPositionColor enough ?
Excuse me, but I am looking for a long time.
class Ocean
{
Effect shader0;
public Vector3 Position;
GraphicsDevice Graphics;
Camera camera;
Model Mesh;
Texture2D waterTexture;
Rectangle screen;
Texture2D test;
public Ocean(Vector3 pos, int size, GraphicsDevice gra, Camera cam, ContentManager content)
{
Graphics = gra;
shader0 = content.Load<Effect>("Ocean");
//shader0 = new BasicEffect(this.Graphics);
waterTexture = content.Load<Texture2D>("Images/shaderUnderwater");
screen = new Rectangle(0, 0, this.Graphics.Viewport.Width, this.Graphics.Viewport.Height);
Position = pos;
Mesh = content.Load<Model>("Models/ocean");
camera = cam;
foreach (ModelMesh mesh in this.Mesh.Meshes)
{
foreach (ModelMeshPart part in mesh.MeshParts)
{
part.Effect = shader0;
}
}
}
bool underWater;
Vector3 lightDirection = new Vector3(-1.0f, -1.0f, -1.0f);
public void Draw(SpriteBatch spriteBatch, Player player)
{
Matrix world = Matrix.CreateScale(100f) * Matrix.CreateRotationX(MathHelper.ToRadians(-90f)) * Matrix.CreateTranslation(Position);
//this.shader0.EnableDefaultLighting();
this.shader0.Parameters["World"].SetValue(world);
this.shader0.Parameters["View"].SetValue(player.Camera.View);
this.shader0.Parameters["Projection"].SetValue(player.Camera.Projection);
// Dessin du model
foreach (ModelMesh mesh in this.Mesh.Meshes)
{
foreach (Effect effect in mesh.Effects)
{
effect.CurrentTechnique = effect.Techniques["Textured"];
effect.Parameters["DiffuseColor"].SetValue(new Vector4(1f, 0.2f, 0.2f, 1f) ); // a reddish light
effect.Parameters["DiffuseLightDirection"].SetValue(new Vector3(1, 0, 0) ); // coming along the x-axis
effect.Parameters["SpecularColor"].SetValue(new Vector4(0, 1, 0 ,1f) ); // with green highlights
effect.Parameters["World"].SetValue(world);
effect.Parameters["View"].SetValue(player.Camera.View);
effect.Parameters["Projection"].SetValue(player.Camera.Projection);
}
mesh.Draw();
}
this.Graphics.BlendState = BlendState.Opaque;
//Effet
if (camera.Position.Y < Position.Y)
spriteBatch.Draw(this.waterTexture, this.screen, Color.White);
}
public void Update(GameTime gameTime)
{
}
void onWater()
{
underWater = true;
}
}
}

If you are using the BasicEffect to render the ocean, then BasicEffect has an Alpha property, which affects the transparency. Please see here: http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.basiceffect.alpha.aspx
You can use BasicEffect to create transparency with any way that you are using for rendering your model.

Related

How to Flip FaceOSC in Processing3.2.1

I am new to the Processing and now trying to use FaceOSC. Everything was done already, but it is hard to play the game I made when everything is not a mirror view. So I want to flip the data that FaceOSC sent to processing to create video.
I'm not sure if FaceOSC sent the video because I've tried flip like a video but it doesn't work. I also flipped like a image, and canvas, but still doesn't work. Or may be I did it wrong. Please HELP!
//XXXXXXX// This is some of my code.
import oscP5.*;
import codeanticode.syphon.*;
OscP5 oscP5;
SyphonClient client;
PGraphics canvas;
boolean found;
PVector[] meshPoints;
void setup() {
size(640, 480, P3D);
frameRate(30);
initMesh();
oscP5 = new OscP5(this, 8338);
// USE THESE 2 EVENTS TO DRAW THE
// FULL FACE MESH:
oscP5.plug(this, "found", "/found");
oscP5.plug(this, "loadMesh", "/raw");
// plugin for mouth
oscP5.plug(this, "mouthWidthReceived", "/gesture/mouth/width");
oscP5.plug(this, "mouthHeightReceived", "/gesture/mouth/height");
// initialize the syphon client with the name of the server
client = new SyphonClient(this, "FaceOSC");
// prep the PGraphics object to receive the camera image
canvas = createGraphics(640, 480, P3D);
}
void draw() {
background(0);
stroke(255);
// flip like a vdo here, does not work
/* pushMatrix();
translate(canvas.width, 0);
scale(-1,1);
image(canvas, -canvas.width, 0, width, height);
popMatrix(); */
image(canvas, 0, 0, width, height);
if (found) {
fill(100);
drawFeature(faceOutline);
drawFeature(leftEyebrow);
drawFeature(rightEyebrow);
drawFeature(nosePart1);
drawFeature(nosePart2);
drawFeature(leftEye);
drawFeature(rightEye);
drawFeature(mouthPart1);
drawFeature(mouthPart2);
drawFeature(mouthPart3);
drawFeature(mouthPart4);
drawFeature(mouthPart5);
}
}
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
void drawFeature(int[] featurePointList) {
for (int i = 0; i < featurePointList.length; i++) {
PVector meshVertex = meshPoints[featurePointList[i]];
if (i > 0) {
PVector prevMeshVertex = meshPoints[featurePointList[i-1]];
line(meshVertex.x, meshVertex.y, prevMeshVertex.x, prevMeshVertex.y);
}
ellipse(meshVertex.x, meshVertex.y, 3, 3);
}
}
/XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
public void found(int i) {
// println("found: " + i); // 1 == found, 0 == not found
found = i == 1;
}
//XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
The scale() and translate() snippet you're trying to use makes sense, but it looks like you're using it in the wrong place. I'm not sure what canvas should do, but I'm guessing the face features is drawn using drawFeature() calls is what you want to mirror. If so, you should do place those calls in between pushMatrix() and popMatrix() calls, right after the scale().
I would try something like this in draw():
void draw() {
background(0);
stroke(255);
//flip horizontal
pushMatrix();
translate(width, 0);
scale(-1,1);
if (found) {
fill(100);
drawFeature(faceOutline);
drawFeature(leftEyebrow);
drawFeature(rightEyebrow);
drawFeature(nosePart1);
drawFeature(nosePart2);
drawFeature(leftEye);
drawFeature(rightEye);
drawFeature(mouthPart1);
drawFeature(mouthPart2);
drawFeature(mouthPart3);
drawFeature(mouthPart4);
drawFeature(mouthPart5);
}
popMatrix();
}
The push/pop matrix calls isolate the coordinate space.
The coordinate system origin(0,0) is the top left corner: this is why everything is translated by the width before scaling x by -1. Because it's not at the centre, simply mirroring won't leave the content in the same place.
For more details checkout the Processing Transform2D tutorial
Here's a basic example:
boolean mirror;
void setup(){
size(640,480);
}
void draw(){
if(mirror){
pushMatrix();
//translate, otherwise mirrored content will be off screen (pivot is at top left corner not centre)
translate(width,0);
//scale x -= 1 mirror
scale(-1,1);
//draw mirrored content
drawStuff();
popMatrix();
}else{
drawStuff();
}
}
//this could be be the face preview
void drawStuff(){
background(0);
triangle(0,0,width,0,0,height);
text("press m to toggle mirroring",450,470);
}
void keyPressed(){
if(key == 'm') mirror = !mirror;
}
Another option is to mirror each coordinate, but in your case it would be a lot of effort when scale(-1,1) will do the trick. For reference, to mirror the coordinate, you simply need to subtract the current value from the largest value:
void setup(){
size(640,480);
background(255);
}
void draw(){
ellipse(mouseX,mouseY,30,30);
//subtract current value(mouseX in this case) from the largest value it can have (width in this case)
ellipse(width-mouseX,mouseY,30,30);
}
You can run these examples right here:
var mirror;
function setup(){
createCanvas(640,225);
fill(255);
}
function draw(){
if(mirror){
push();
//translate, otherwise mirrored content will be off screen (pivot is at top left corner not centre)
translate(width,0);
//scale x -= 1 mirror
scale(-1,1);
//draw mirrored content
drawStuff();
pop();
}else{
drawStuff();
}
}
//this could be be the face preview
function drawStuff(){
background(0);
triangle(0,0,width,0,0,height);
text("press m to toggle mirroring",450,470);
}
function keyPressed(){
if(key == 'M') mirror = !mirror;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.4/p5.min.js"></script>
function setup(){
createCanvas(640,225);
background(0);
fill(0);
stroke(255);
}
function draw(){
ellipse(mouseX,mouseY,30,30);
//subtract current value(mouseX in this case) from the largest value it can have (width in this case)
ellipse(width-mouseX,mouseY,30,30);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/0.5.4/p5.min.js"></script>

XNA model with bones

I created a model in Blender and then I used armature to create some pose. How can I display this pose in XNA/MonoGame? I can't find any solution. I use model exported to fbx file.
My only code is here and it draws model without armature effect:
protected override void Draw(GameTime gameTime)
{
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
// Copy any parent transforms.
Matrix[] transforms = new Matrix[myModel.Bones.Count];
myModel.CopyAbsoluteBoneTransformsTo(transforms);
// Draw the model. A model can have multiple meshes, so loop.
foreach (ModelMesh mesh in myModel.Meshes)
{
// This is where the mesh orientation is set, as well as our camera and projection.
foreach (BasicEffect effect in mesh.Effects)
{
effect.EnableDefaultLighting();
effect.World = transforms[mesh.ParentBone.Index] * Matrix.CreateRotationY(modelRotation)
* Matrix.CreateTranslation(modelPosition);
effect.View = Matrix.CreateLookAt(cameraPosition, Vector3.Zero, Vector3.Up);
effect.Projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.ToRadians(45.0f),
aspectRatio, 1.0f, 10000.0f);
}
// Draw the mesh, using the effects set above.
mesh.Draw();
}
base.Draw(gameTime);
}

Sprite walking and background moving too: XNA

I would like to make a simple thing in XNA where the background would move when the character moves to the right.
Any ideas how to do it?
thanks
I think you mean like in the game Mario!
Using Scrolling.
Create the game class.
Load resources as described in the procedures of Drawing a Sprite.
Load the background texture.
private ScrollingBackground myBackground;
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
myBackground = new ScrollingBackground();
Texture2D background = Content.Load<Texture2D>("starfield");
myBackground.Load(GraphicsDevice, background);
}
Determine the size of the background texture and the size of the screen.
The texture size is determined using the Height and Width properties, and the screen size is determined using the Viewport property on the graphics device.
Using the texture and screen information, set the origin of the texture to the center of the top edge of the texture, and the initial screen position to the center of the screen.
// class ScrollingBackground
private Vector2 screenpos, origin, texturesize;
private Texture2D mytexture;
private int screenheight;
public void Load( GraphicsDevice device, Texture2D backgroundTexture )
{
mytexture = backgroundTexture;
screenheight = device.Viewport.Height;
int screenwidth = device.Viewport.Width;
// Set the origin so that we're drawing from the
// center of the top edge.
origin = new Vector2( mytexture.Width / 2, 0 );
// Set the screen position to the center of the screen.
screenpos = new Vector2( screenwidth / 2, screenheight / 2 );
// Offset to draw the second texture, when necessary.
texturesize = new Vector2( 0, mytexture.Height );
}
To scroll the background, change the screen position of the background texture in your Update method.
This example moves the background down 100 pixels per second by increasing the screen position's Y value.
protected override void Update(GameTime gameTime)
{
...
// The time since Update was called last.
float elapsed = (float)gameTime.ElapsedGameTime.TotalSeconds;
// TODO: Add your game logic here.
myBackground.Update(elapsed * 100);
base.Update(gameTime);
}
The Y value is kept no larger than the texture height, making the background scroll from the bottom of the screen back to the top.
public void Update( float deltaY )
{
screenpos.Y += deltaY;
screenpos.Y = screenpos.Y % mytexture.Height;
}
// ScrollingBackground.Draw
Draw the background using the origin and screen position calculated in LoadContent and Update.
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
myBackground.Draw(spriteBatch);
spriteBatch.End();
base.Draw(gameTime);
}
In case the texture doesn't cover the screen, another texture is drawn. This subtracts the texture height from the screen position using the texturesize vector created at load time. This creates the illusion of a loop.
public void Draw( SpriteBatch batch )
{
// Draw the texture, if it is still onscreen.
if (screenpos.Y < screenheight)
{
batch.Draw( mytexture, screenpos, null,
Color.White, 0, origin, 1, SpriteEffects.None, 0f );
}
// Draw the texture a second time, behind the first,
// to create the scrolling illusion.
batch.Draw( mytexture, screenpos - texturesize, null,
Color.White, 0, origin, 1, SpriteEffects.None, 0f );
}

Coordinates of a Texture2d?

I know you can get the width and height of class Texture2d, but why can't you get the x and y coordinates? Do I have to create separate variables for them or something? Seems like a lot of work.
You must use a Vector2-object in association with a Texture2D-object. A Texture2D-object itself does not have any coordinates.
When you want to draw a texture, you will need a SpriteBatch to draw it, whereas this takes a Vector2D to determine the coordinates.
public void Draw (
Texture2D texture,
Vector2 position,
Color color
)
This is taken from MSDN.
So, either create a struct
struct VecTex{
Vector2 Vec;
Texture2D Tex;
}
or a class when you need further processing.
A Texture2D object alone doesn't have any screen x and y coordinates.
In order to draw a texture on the screen, you must either set it's position by using a Vector2 or a Rectangle.
Here's an example using Vector2:
private SpriteBatch spriteBatch;
private Texture2D myTexture;
private Vector2 position;
// (...)
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// Load the Texture2D object from the asset named "myTexture"
myTexture = Content.Load<Texture2D>(#"myTexture");
// Set the position to coordinates x: 100, y: 100
position = new Vector2(100, 100);
}
protected override void Draw(GameTime gameTime)
{
spriteBatch.Begin();
spriteBatch.Draw(myTexture, position, Color.White);
spriteBatch.End();
}
And here's an example using Rectangle:
private SpriteBatch spriteBatch;
private Texture2D myTexture;
private Rectangle destinationRectangle;
// (...)
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// Load the Texture2D object from the asset named "myTexture"
myTexture = Content.Load<Texture2D>(#"myTexture");
// Set the destination Rectangle to coordinates x: 100, y: 100 and having
// exactly the same width and height of the texture
destinationRectangle = new Rectangle(100, 100,
myTexture.Width, myTexture.Height);
}
protected override void Draw(GameTime gameTime)
{
spriteBatch.Begin();
spriteBatch.Draw(myTexture, destinationRectangle, null, Color.White);
spriteBatch.End();
}
The main difference is that by using a Rectangle you are able to scale your texture to fit the destination rectangle's width and height.
You can find some more information about the SpriteBatch.Draw method at MSDN.

SlimDX Camera setup

Please, tell me what I'm doing wrongly:
that's my Camera class
public class Camera
{
public Matrix view;
public Matrix world;
public Matrix projection;
public Vector3 position;
public Vector3 target;
public float fov;
public Camera(Vector3 pos, Vector3 tar)
{
this.position = pos;
this.target = tar;
view = Matrix.LookAtLH(position, target, Vector3.UnitY);
projection = Matrix.PerspectiveFovLH(fov, 1.6f, 0.001f, 100.0f);
world = Matrix.Identity;
}
}
that's my Constant buffer struct:
struct ConstantBuffer
{
internal Matrix mWorld;
internal Matrix mView;
internal Matrix mProjection;
};
and here I'm drawing the triangle and setting camera:
x+= 0.01f;
camera.position = new Vector3(x, 0.0f, 0.0f);
camera.view = Matrix.LookAtLH(camera.position, camera.target, Vector3.UnitY);
camera.projection = Matrix.PerspectiveFovLH(camera.fov, 1.6f, 0.0f, 100.0f);
var buffer = new Buffer(device, new BufferDescription
{
Usage = ResourceUsage.Default,
SizeInBytes = sizeof(ConstantBuffer),
BindFlags = BindFlags.ConstantBuffer
});
////////////////////////////// camera setup
ConstantBuffer cb;
cb.mProjection = Matrix.Transpose(camera.projection);
cb.mView = Matrix.Transpose(camera.view);
cb.mWorld = Matrix.Transpose(camera.world);
var data = new DataStream(sizeof(ConstantBuffer), true, true);
data.Write(cb);
data.Position = 0;
context.UpdateSubresource(new DataBox(0, 0, data), buffer, 0);
//////////////////////////////////////////////////////////////////////
// set the shaders
context.VertexShader.Set(vertexShader);
context.PixelShader.Set(pixelShader);
// draw the triangle
context.Draw(4, 0);
swapChain.Present(0, PresentFlags.None);
Please, if you can see what's wrong, tell me! :) I have spent two days writing this already..
Attempt the second:
#paiden I initialized fov now ( thanks very much :) ) but still no effect (now it's fov = 1.5707963267f;) and #Nico Schertler , thank you too, I put it in use by
context.VertexShader.SetConstantBuffer(buffer, 0);
context.PixelShader.SetConstantBuffer(buffer, 0);
but no effect still... probably my .fx file is wrong? for what purpose do I need this:
cbuffer ConstantBuffer : register( b0 ) { matrix World; matrix View; matrix Projection; }
Attepmpt the third:
#MHGameWork
Thank you very much too, but no effect still ;)
If anyone has 5 minutes time, I can just drop source code to his/her e-mail and then we will publish the answer... I guess it will help much to some newbies like me :)
unsafe
{
x+= 0.01f;
camera.position = new Vector3(x, 0.0f, 0.0f);
camera.view = Matrix.LookAtLH(camera.position, camera.target, Vector3.UnitY);
camera.projection = Matrix.PerspectiveFovLH(camera.fov, 1.6f, 0.01f, 100.0f);
var buffer = new Buffer(device, new BufferDescription
{
Usage = ResourceUsage.Default,
SizeInBytes = sizeof(ConstantBuffer),
BindFlags = BindFlags.ConstantBuffer
});
THE PROBLEM NOW - I SEE MY TRIANGLE BUT THE CAMERA DOESN'T MOVE
You have set your camera's nearplane to 0. This makes all the value in your matrix divide by zero, so you get a matrix filled with 'NAN's
Use a near plane value of about 0.01 in your case, it will solve the problem
I hope you still need help. Here is my camera class, which can be used, and can be easily moved around the scene using mouse/keyboard.
http://pastebin.com/JtiUSiHZ
Call the "TakeALook()" method in each frame (or when you move the camera).
You can move around it with the "CameraMove" method. It takes a Vector3 - where you want to move your camera (dont give it huge values, I use 0,001f for each frame)
And with the "CameraRotate()" you can turn it around - it take a Vector2 as a Left-Right and Up-Down rotation.
Its pretty easy. I use EventHandlers to call there two function, but feel free to edit as you wish.

Resources