Hi i need to create a texture that is made up of other textures overlayed. I've tried using pixmap however it is noticably slow. The idea is to create a "snapshot" of a dialog so that it can be animated as it shows up and when it is dismissed. Please help
This is the code that I am using:
texture_dialog.getTextureData().prepare();
Pixmap pm1 = texture_dialog.getTextureData().consumePixmap();
btn_ok.getTexture().getTextureData().prepare();
Pixmap pm = btn_ok.getTexture().getTextureData().consumePixmap();
pm1.drawPixmap(pm, pm1.getWidth()/2 - pm.getWidth()/2, pm1.getHeight() - pm.getHeight() - 52);
textureSnapShot = new Texture(pm1, true);
pm1.dispose();
pm.dispose();
textureSnapShot.setFilter(TextureFilter.MipMapLinearLinear, TextureFilter.MipMapLinearLinear);
spriteSnapShot = new Sprite(textureSnapShot);
I've tried using a FrameBuffer as follows:
SpriteBatch sb = new SpriteBatch();
sb.setProjectionMatrix(camera.combined);
FrameBuffer fbo = new FrameBuffer(Format.RGBA8888, texture_dialog.getWidth(), texture_dialog.getHeight(), false);
fbo.begin();
sb.begin();
sb.draw(texture_dialog, 0, 0);
sb.draw(btn_ok.getTexture(), texture_dialog.getWidth()/2 - btn_ok.getWidth()/2, 52);
sb.end();
fbo.end();
sb.dispose();
textureSnapShot = fbo.getColorBufferTexture();
//textureSnapShot.setFilter(TextureFilter.MipMapLinearLinear, TextureFilter.MipMapLinearLinear);
spriteSnapShot = new Sprite(textureSnapShot);
The results are as follows:
http://medialinestudio.co.za/screens.png
Left: Pixmap Right: FrameBuffer
Pixmap has the correct result but too slow. FrameBuffer is faster but incorrect result
FBO is definitely what you should use for your need.
read this post : libgdx SpriteBatch render to texture
what you missing is :
create a camera with correct width/height and position to fit your drawing inside the FBO viewport (0,0,Width,Height)
flip the output texture (m_fboRegion.flip(false, true))
Related
I'm developing an app with blazor client-side and I need to render a 3D scene.
I have an issue and I guess it is material-related.
I have a composition of parallelepipeds where one of them is fully opaque and the others are transparent.
Depending on the camera angle, the transparent ones completely disappear:
Example where everything is visible:
Example with 2 missing:
Example with all missing:
Code for transparent parallelepipeds
var geometry = new THREE.CubeGeometry(item.xDimension * _scene.normalizer, item.yDimension * _scene.normalizer, item.zDimension * _scene.normalizer);
var material = new THREE.MeshBasicMaterial();
var box = new THREE.Mesh(geometry, material);
box.material.color = new THREE.Color("gray");
box.material.opacity = 0.8;
box.material.transparent = true;
Code for the camera:
var camera = new THREE.PerspectiveCamera(60, width / height, 0.1, 100);
camera.position.set(1.3, 1.3, 1.3);
camera.lookAt(0, 0, 0);
I'm using OrbitControls and every object size is between 0 an 1 (_scene.normalizer is for that purpose)
Do you know why this is happening?
Edit:
I found it being a material depth function issue. Do you know which should I use?
Thanks,
Transparency is tricky with WebGL because a transparent object writes to the depthmap, and then the renderer assumes that subsequent objects behind it are occluded so it skips drawing them. You could avoid this by playing with the material's .depthTest and .depthWrite attributes (see the docs):
box.material.color = new THREE.Color("gray");
box.material.opacity = 0.8;
box.material.transparent = true;
box.material.depthWrite = false;
I'm programming a game in XNA, using VB.NET. I want to create an intro to the game that zooms in/out the whole screen and scaling each image to accomplish this is cumbersome at best. I like to be able to draw a lot of .PNG's (or parts of them) onto a whole image, to then be able to manipulate (scale, turn etc) that whole image, before drawing it with the spriteBatch. The examples I can find use something like:
dim bitmap as New Bitmap
or
dim image as New Image
but these codes highlights the "Bitmap" or "Image" as red, and I cannot use them. I'd be thankful for any help on this issue!
SpriteBatch works with XNA Texture2D objects, whereas Bitmap and Image are System.Drawing types. They do not work together.
You can create a new RenderTarget2D, set it as active using GraphicsDevice.SetRenderTarget() and draw there using a SpriteBatch. You can then draw the stored render target to screen using a SpriteBatch, since render targets are a type of Texture2D.
So I've experimented with Petri Laarne's answer and finally come up with a workable code (most examples online are using C#, and doesn't explain the entire process). Trying to explain it here:
In Public Class Game1:
Private WithEvents graphics As GraphicsDeviceManager
Private WithEvents spriteBatch, spriteBatch2 As SpriteBatch
In Loadcontent:
Public render2 As RenderTarget2D
spriteBatch2 = New SpriteBatch(GraphicsDevice)
spriteBatch = New SpriteBatch(GraphicsDevice)
render2 = New RenderTarget2D(GraphicsDevice, 1024, 768)
In Draw:
spriteBatch2.GraphicsDevice.SetRenderTarget(render2)
GraphicsDevice.Clear(Color.Black)
srcRect = New Rectangle(440, 0, 440, 440) : destRect = New Rectangle(100, 335, 440, 440)
spriteBatch2.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend) : spriteBatch2.Draw(introNEWMirrorDecos, destRect, srcRect, Color.White) : spriteBatch2.End()
destRect = New Rectangle(300, 335, 440, 440)
spriteBatch2.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend) : spriteBatch2.Draw(introNEWMirrorDecos, destRect, srcRect, Color.White) : spriteBatch2.End()
spriteBatch2.GraphicsDevice.SetRenderTarget(Nothing)
GraphicsDevice.Clear(Color.Black)
destRect = New Rectangle(512, 384, 1024, 768) : srcRect = New Rectangle(0, 0, 1024, 768)
spriteBatch.Begin(SpriteSortMode.BackToFront, BlendState.AlphaBlend) : spriteBatch.Draw(render2, destRect, srcRect, Color.White, PI / 12, New Vector2(512, 384), SpriteEffects.None, 0) : spriteBatch.End()
This is an example code from the actual game that worked like it was intended: drawing 2 things on the alternate rendering image and then drawing them as one single image (in this case being able to rotate it by pi/12).
Any comments on how to do this differently or more efficient is appreciated, and thank's for the initial answer #Petri Laarne
Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
How I can Crop / Clip images in WinRT. I have an image filled completely in a windows 8 window. I need to clip / crop the image from center and i need to display the two image section into two separate grids. How I can do the same through windows 8. Is it possible to implement this without using WritableBitmapEx. If no, how to do the same through WritableBitmapEx.
There are many ways to do it actually, each with some pros and cons.
WriteableBitmapEx seems like a popular solution. I have a similar implementation in WinRT XAML Toolkit. Both are essentially copying blocks of pixels from a full image bitmap. It might not be the fastest way, but if you'd want to get an out of the box solution - it is one that is easy to use. You need to copy the pixels, so you are not optimizing for memory use at the time of the operation and so might run out of memory on very large images quicker. You can recrop easily though end save the results to an image file if you want.
The BitmapDecoder solution Jan recommended is one I often use as it is part of the platform, written in native code and possibly highly optimized and you don't copy the pixels, but if you want to recrop - you'll need to decode the image again.
Xyroid's suggestion with Clip geometry is a quick display-only solution. You don't actually modify the bitmap in memory - you simply display a region of it on the screen. You need then to keep the entire image in memory and if you want to save it - you still need to update the bitmap to save it - by using either one of the first two solutions or maybe use RenderTargetBitmap.Render() if screen resolution is enough for you. It should be very quick though to update the crop region displayed on the screen for quick preview.
Another one is with a Rectangle filled with an ImageBrush where you can apply a Transform and specify the Rectangle size to control cropping. It is fairly similar to the Clip solution only instead of clipping an image and in this case you actually have to use the Tramsform (which you can also do on a Clip - RectangleGeometry). For quick updates - using a Transform might actually be a bit faster than updating the geometry and also supports scaling and rotations.
You can use the Bitmapdecoder and the BitmapTransform classes. This example is very good for cropping. You should also read this tutorial for clipping. Basically you implement a function like this (taken from the example):
async public static Task<ImageSource> GetCroppedBitmapAsync(StorageFile originalImgFile, Point startPoint, Size corpSize, double scale)
{
if (double.IsNaN(scale) || double.IsInfinity(scale))
{
scale = 1;
}
// Convert start point and size to integer.
uint startPointX = (uint)Math.Floor(startPoint.X * scale);
uint startPointY = (uint)Math.Floor(startPoint.Y * scale);
uint height = (uint)Math.Floor(corpSize.Height * scale);
uint width = (uint)Math.Floor(corpSize.Width * scale);
using (IRandomAccessStream stream = await originalImgFile.OpenReadAsync())
{
// Create a decoder from the stream. With the decoder, we can get
// the properties of the image.
BitmapDecoder decoder = await BitmapDecoder.CreateAsync(stream);
// The scaledSize of original image.
uint scaledWidth = (uint)Math.Floor(decoder.PixelWidth * scale);
uint scaledHeight = (uint)Math.Floor(decoder.PixelHeight * scale);
// Refine the start point and the size.
if (startPointX + width > scaledWidth)
{
startPointX = scaledWidth - width;
}
if (startPointY + height > scaledHeight)
{
startPointY = scaledHeight - height;
}
// Create cropping BitmapTransform and define the bounds.
BitmapTransform transform = new BitmapTransform();
BitmapBounds bounds = new BitmapBounds();
bounds.X = startPointX;
bounds.Y = startPointY;
bounds.Height = height;
bounds.Width = width;
transform.Bounds = bounds;
transform.ScaledWidth = scaledWidth;
transform.ScaledHeight = scaledHeight;
// Get the cropped pixels within the bounds of transform.
PixelDataProvider pix = await decoder.GetPixelDataAsync(
BitmapPixelFormat.Bgra8,
BitmapAlphaMode.Straight,
transform,
ExifOrientationMode.IgnoreExifOrientation,
ColorManagementMode.ColorManageToSRgb);
byte[] pixels = pix.DetachPixelData();
// Stream the bytes into a WriteableBitmap
WriteableBitmap cropBmp = new WriteableBitmap((int)width, (int)height);
Stream pixStream = cropBmp.PixelBuffer.AsStream();
pixStream.Write(pixels, 0, (int)(width * height * 4));
return cropBmp;
}
}
XAML static way, if my screen size is 1366x768 & I want to clip center 400x300 image then I would do this.
<Image Source="Assets/img100.png" Stretch="Fill">
<Image.Clip>
<RectangleGeometry Rect="483,234,400,300" />
</Image.Clip>
</Image>
Dynamic way. It will make center clipping for all resolution, though height & width is fixed.
double _Height = 300, _Width = 400;
img.Clip = new RectangleGeometry
{
Rect = new Rect((Window.Current.Bounds.Width - _Width) / 2, (Window.Current.Bounds.Height - _Height) / 2, _Width, _Height)
};
Don't forget to checkout...
How to resize Image in C# WinRT/winmd?
Crop image with rectangle
Crop image with dynamic rectangle coordinate
Cropping tool after file picker (like the one after you take a picture)
I'm trying to create an additional visibility rectangle on a main Scene.
So I'v a main Camera 480x800 that is showing me a scene as it is and i'd like to attach an aditional entity or a scene that will have a rectangle of visibility.
So if I'll drag items inside it they will not dissapier in a single moment they will dissapier gradually.
As described in my previous comment you could stamp out a square alpha hole in your background Sprite. You could do this simply with an image editor, adding alpha pixels or you could do it dynamically as follows,
//set the background to white - so we can see our square alpha
//cut out later
mScene.setBackground(new ColorBackground(1.0f, 1.0f, 1.0f));
//Create and load bitmap texture atlas
BitmapTextureAtlas mBitmapBGTextureAtlas = new BitmapTextureAtlas(1024, 1024, TextureOptions.BILINEAR_PREMULTIPLYALPHA);
mActivity.getEngine().getTextureManager().loadTextures(mBitmapBGTextureAtlas);
//Get image in assets and decode into bitmap
InputStream ims;
try {
ims = mActivity.getAssets().open("gfx/my_backgound.jpg");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
return;
}
Bitmap Bitmap_bg = BitmapFactory.decodeStream(ims);
//In my case the image is different than the height and width of the camera
//so store the ratio of size and height that the image will be resized to
float XScale = Bitmap_bg.getWidth()/mCamera.getWidth();
float YScale = Bitmap_bg.getHeight()/mCamera.getHeight();
//Cut out the alpha square, if our camera is 480x800, the square will appear
//at (40,200) and will be size 400x400
Bitmap_bg = cutSquareOutOfBitmap(Bitmap_bg, 40 * XScale, 200 * YScale, 400 * XScale , 400 * YScale);
//Get our edited bitmap into a region of the texture atlas
BitmapTextureAtlasSource source = new BitmapTextureAtlasSource(Bitmap_bg);
mBackground = BitmapTextureAtlasTextureRegionFactory.createFromSource(mBitmapBGTextureAtlas, source, 0, 0);
Bitmap_bg.recycle();
//Finally, create our background sprite with this new texture region
Sprite mBackgroundSprite = new Sprite(0, 0, mCamera.getWidth(), mCamera.getHeight(), mBackground);
mBackgroundSprite.setZIndex(1);
mScene.attachChild(mBackgroundSprite);
And the function cutSquareOutOfBitmap()
public static Bitmap cutSquareOutOfBitmap(Bitmap MyImage, float Xpos, float Ypos, float Width, float Height) {
Bitmap mBitmap = MyImage.copy(Bitmap.Config.ARGB_8888, true);
Paint mPaint = new Paint();
Canvas mCanvas = new Canvas(mBitmap );
mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
mPaint .setXfermode(new PorterDuffXfermode(Mode.SRC_OUT));
mPaint .setColor(Color.TRANSPARENT);
mCanvas.drawBitmap(mBitmap , 0, 0, null);
mCanvas.drawRect(Xpos, Ypos, Xpos + Width, Ypos + Height, mPaint );
return mBitmap ;
}
If you run this - not a lot to look at but a big white square, however, this is a transparent region, the square is actually the background we set earlier.
To demonstrate how the contents will be obscured, you could create a scrollable area, as mentioned in my previous comment I wrote a small container class you are welcome to use,
Custom ScrollView in andengine
Underneath the first code block in this answer, after,
mScene.attachChild(mBackgroundSprite);
You could now add,
//Now we can use the ShapeScrollContainer just as an example so the user can
//scroll our container shapes around
//Create it around the same area as the cut out
ShapeScrollContainer mShapeScrollContainer = new ShapeScrollContainer(40, 200, 400, 400, new IShapeScrollContainerTouchListener() {
#Override
public void OnContentClicked(Shape pShape) {
// TODO Auto-generated method stub
//Add code here for content click event
}
});
//Disable the ShapeScrollContainer ability to change the visibility
//of contents - we no longer require this as the background will
//cover them outside of the bounds of the ShapeScrollContainer itself
mShapeScrollContainer.SetContentVisiblitiyControl(false);
//Disable alpha
mShapeScrollContainer.SetAlphaVisiblitiyControl(false);
//Allow user to scroll both horizontally and vertically
mShapeScrollContainer.SetScrollableDirections(true, true);
//Don't allow the user to scroll to no where
mShapeScrollContainer.SetScrollLock(true);
//Allow use to scroll half the container over in either direction
mShapeScrollContainer.SetScrollLockPadding(50.0f,50.0f);
//Attach the container to the scene and register the event listener
mScene.registerTouchArea(mShapeScrollContainer);
mScene.attachChild(mShapeScrollContainer);
//Finally add some content to the container, what ever extends Shape,
//Sprite, Animated Sprite, Text, ChangeableText e.t.c.
Rectangle mRectangle = new Rectangle(200, 360, 80, 80);
mRectangle.setColor(0.0f, 1.0f, 0.0f);
mRectangle.setZIndex(0);
//Attach to the scene and the ShapeScrollContainer
mScene.attachChild(mRectangle);
mShapeScrollContainer.Add(mRectangle);
Rectangle mRectangle2 = new Rectangle(40, 360, 80, 80);
mRectangle2.setColor(0.0f, 0.0f, 1.0f);
mRectangle2.setZIndex(0);
mScene.attachChild(mRectangle2);
mShapeScrollContainer.Add(mRectangle2);
Rectangle mRectangle3 = new Rectangle(360, 360, 80, 80);
mRectangle3.setColor(1.0f, 1.0f, 0.0f);
mRectangle3.setZIndex(0);
mScene.attachChild(mRectangle3);
mShapeScrollContainer.Add(mRectangle3);
//And sort the order in which shapes are rendered
mScene.sortChildren();
Now you should get something like the following after scrolling,
As another alternative if you are going for a simpler background you could forgo the bitmap manipulation and simply make the square with four surrounding rectangles making up the sides to the edge of the screen.
Or you could physically split your background into 4 surrounding rectangles and a central square with an image editor. Then create 5 sprites, set the z order of the four rectangles to 2, the square to 0 and any content sprites to 1.
Hope this is of use.
I am doing DoubleAnimation of the Width property of a Canvas. I want to shrink the canvas to 1/5 th of the size.
var widthAnimation = new DoubleAnimation();
widthAnimation.Duration = new TimeSpan(0,0,1);
StoryBoard.SetTarget(widthAnimation, Canvas1);
StoryBoard.SetTargetProperty(widthAnimation, new PropertyPath("Width"));
widthAnimation.From = Canvas1.Width;
widthAnimation.To = Canvas1.Width * .2;
StoryBoard stb = new StoryBoard();
stb.Children.Add(widthAnimation);
stb.Begin();
Somehow, the above animation does not shrink the size to 1/5th. Instead, it enlarges the canvas. Any clues why the animation is doing something funny?
The canvas was wrapped in a viewbox. The Viewbox size was fixed, while the canvas within it shrinked. The text expanded. Not sure why. But, I fixed the problem by applying the animation to the Viewbox rather than the Canvas. And it works all fine now.