I am trying to render some sprites and I need the line batch.setProjectionMatrix(cam.combined); in order for the sprites to move independently from the camera, however when I add this line the sprites suddenly turn abnormally large, but without it they are just normal. I have the suspicion that it changes the world dimensions or something like that, because the the boundaries I set for the player sprite are also expanded, just like the size of the sprites, but the background (a tiledmap rendered with a OrthogonalTiledMapRenderer) stays the same.
This is the normal rendering as it should be: https://ibb.co/m4T2GT
This is the rendering i get when using setProjectionMatrix: https://ibb.co/j0EL38
(I used an external site for the pictures because for some reason I could not add them here)
This is my render function.
player.draw(..);
and
e.draw(..);
just call the draw function of the Sprite class.
public void render() {
handleInput();
renderer.setView(cam);
renderer.render();
batch.setProjectionMatrix(cam.combined);
batch.begin();
player.draw(batch);
for (Entity e: enemies) e.draw(batch);
batch.end();
}
You can use the float: cam.zoom to change how large everything appears. Change it in setup or just after you initialise the camera object, then it should remain at that zoom.
If that doesn't work, you might need to set the map rendering to the camera's projection matrix as well.
Related
I have a custom view that allow me to draw lines on canvas and it works fine .
what I want is to see the drawing while its drawing in the foreground and make the user control the speed of drawing and can it be convert the drawing period to video ?
my code for drawing lines is
public ArrayList<BlockDraw> drawers = new ArrayList<>();
public void draw(Canvas canvas) {
for (BlockDraw blockDraw : drawers) {
canvas.drawLines(blockDraw.list.pointlist, 0, blockDraw.list.count, blockDraw.paint);
}}
If you have a custom view, onDraw gets called when the view needs to update, and you draw on the canvas to create the new image. It's just a single image, drawLines is just a convenient way of drawing a bunch of stuff.
You can call invalidate() at the end of onDraw to make it fire next frame, so you're constantly redrawing the canvas - that will let you create an animation by changing what you draw over time, e.g. gradually increasing the end value in drawLines from 0 to blockDraw.list.count (depending on the "draw speed" you let the user set).
That would just let you draw 1 line, then 2 lines, then 3 etc. If you want to animate each line actually extending from its start point, like you're watching it being drawn by a pen, that's a lot more complex, but you'd do it the same way! Each frame, calculate what needs to be drawn and draw it, depends on how complex you want to make it.
Video is a whole other thing, the emulator will let you record video of your app if that's what you want.
I've been trying to draw an image of a block with an eye on the screen. I want to be able to animate more than one texture in the same way, so drawing the animations by hand is not an option. The problem is that when I move the eyelid sprite higher up than completely closed, part of the eyelid shows above the expected bounds like this. Obviously, this is a problem as it looks quite unnatural. I'd like to either have an alternative solution to this problem, or be able to crop the eyelid's Sprite object to fit behind the rest of the image. The final image consists of the eyeball, pupil (as I want to be able to animate this too), eyelid, main body and the outlines, drawn in that order. The render function looks like this:
public void render(float delta) {
float height = this.eyelid.getHeight();
float eyeHeight = height*0.7f;
this.eyelid.setY(this.eye.getY()+(eyeHeight*((100-this.lid)/100f)));
batch.begin();
this.eye.draw(batch);
this.pupil.draw(batch);
this.eyelid.draw(batch);
this.main.draw(batch);
this.shade.draw(batch);
batch.end();
}
this.lid is the % of how closed the eye is, and the image for the eyelid itself can be found here. How could I solve this problem, or how could I crop the sprite? I don't want to have to reload the texture as a sprite every frame.
I think what you're looking for is the ScissorStack class, which is documented on the libGDX wiki. You can use this object to clip around the eye's frame so that the top of the lid doesn't show.
I'm trying to create a "progress bar" of sorts but the clipping doesn't seem to work the way I expect it to. Is this something I am doing wrong or something I've misinterpreted?
The draw() routine that should clip:
#Override
public void draw(SpriteBatch batch, float parentAlpha) {
Rectangle scissors = new Rectangle();
Rectangle clipBounds = new Rectangle(getX(), getY(), getWidth() * 0.75f, getHeight());
ScissorStack.calculateScissors(
getStage().getCamera(),
getStage().getGutterWidth(),
getStage().getGutterHeight(),
getStage().getCamera().viewportWidth,
getStage().getCamera().viewportHeight,
batch.getTransformMatrix(),
clipBounds, scissors);
if (ScissorStack.pushScissors(scissors)) {
super.draw(batch, parentAlpha);
ScissorStack.popScissors();
}
}
}
Complete sample code for ClipTest group class, TestScreen and screenshot.
ClipTest is a subclass of group used to demonstrate the "bug".
ClipImage is a subclass of Image, which performs the clipping on draw().
ClipTest has 2 images, background and foreground.
The background is a black image and it should always be the full size of the progress bar.
The foreground is a white image and it's width is clipped depending on the percentage of the bar.
The strange result I've found is that although the foreground is using the clipping class, the background image is the one actually clipped.
The expected result was created using photoshop (as I couldn't produce it via code).
Any idea what's wrong?
Actual drawing doesn't happen until the Batch "flushes", its not the draw call you need to wrap, as that just queues up drawing to be done later.
You need to make sure the OpenGL draw calls happen between enabling and disabling your scissors, so add a flush after the draw. See
https://github.com/libgdx/libgdx/wiki/Clipping,-with-the-use-of-scissorstack
Because a draw call might cause a flush to happen, you need to keep the draw calls inside the active-scissor region. You may also need to flush or end the batch before starting the active scissor region to prevent queued draw calls from before the scissor start getting flushed inside the active scissor region.
I'm using the Slick2D library in order to render text to the screen but in order to render gl shapes like Rect, I need to first disable GL_TEXTURE_2D. I'm just curious as to why that is needed. Why does GL_TEXTURE_2D disable the rendering of shapes?
The way OpenGL works is basically one large, global state machine. When you bind a texture, every triangle you draw afterwards will use that texture.
The issue here is that the text drawing doesn't unbind it's texture afterwards, so the shapes you draw afterwards will be using that texture instead of no texture. The reason why you think it's "disabling" rendering is because the texture is made up of characters with everything else being transparent. What you're seeing is OpenGL drawing your shape with opacity at 0.
What happens when you disable GL_TEXTURE_2D is that the texture gets unbound and you draw regularly without a texture.
Because the string's texture is applied. As you probably don't set any texture coords it probably uses a section of the texture that is transparent and hence you see nothing.
I want to render a particle effect in 3D using the Z coordinate. I've tried to implement a own ParticleEffect using Decals instead of Sprites without success.
Is there any other way to render a ParticleEffect using the Z coordinate? Maybe by manipulating the transformation Matrix of the SpriteBatch?
Update:
working code
// update projection each frame since my camera is moving
spriteBatch.setProjectionMatrix(camera3d.projection);
for (ParticleEffect effect : effects){
spriteBatch.setTransformMatrix(camera3d.view);
spriteBatch.getTransformMatrix().translate(x,y,z); // different for each effect
spriteBatch.getTransformMatrix().scale(0.1f,0.1f,0.1f); //optional
spriteBatch.begin();
effect.draw(spriteBatch, delta);
spriteBatch.end();
spriteBatch.getTransformMatrix().idt();
}
If your 3D effect is a parallax effect, meaning your particles face the camera perpendicularily, you can indeed set the transformation matrix of the SpriteBatch
batch.getTransformMatrix().idt().translate(0, 0, z);
batch.begin();
... do your rendering here
batch.end();
// reset the matrix, so you can use the batch for other stuff
batch.idt();
For a perspective effect you'll also have to use perspective projection. The easiest way to cope with this requirement is to use a PerspectiveCamera instead of an OrthographicCamera.