how to use SpriteBatch draw method - java

SpriteBatch batcher = new SpriteBatch();
batcher.draw(TextureRegion region,
float x,
float y,
float originX,
float originY,
float width,
float height,
float scaleX,
float scaleY,
float rotation)
What is the meaning of originX, originY, scaleX, scaleY, rotation? Also can you please give me an example of their use?

Why don't you look into docs ?
As stated in docs, origin is bottom left corner, originX, originY are offsets from this origin.
For example if you want object rotate around his center, you will do this.
originX = width/2;
originY = height/2;
By specifing scaleX, scaleY, you scale the image, if you want to make Sprite 2x larger, you will set both scaleX and scaleY to number 2.
rotation specifies rotation around origin in degrees.
This code snippet draws texture rotated by 90 degrees around its center
SpriteBatch batch = new SpriteBatch();
Texture texture = new Texture(Gdx.files.internal("data/libgdx.png"));
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
int textureWidth = texture.getWidth();
int textureHeight = texture.getHeight();
float rotationAngle = 90f;
TextureRegion region = new TextureRegion(texture, 0, 0, textureWidth, textureHeight);
batch.begin();
batch.draw(region, 0, 0, textureWidth / 2f, textureHeight / 2f, textureWidth, textureHeight, 1, 1, rotationAngle, false);
batch.end();
or take a look at tutorial here.

Related

Draw text directly under a specified bitmap

p.setColor(Color.parseColor("#D32F2F"));
RectF background = new RectF((float) itemView.getRight() + dX, (float) itemView.getTop(), (float) itemView.getRight(), (float) itemView.getBottom());
c.drawRect(background, p);
icon = getBitmapFromVectorDrawable(MainActivity.this, R.drawable.ic_clear);
RectF icon_dest = new RectF((float) itemView.getRight() - 2 * width, (float) itemView.getTop() + width, (float) itemView.getRight() - width, (float) itemView.getBot
c.drawBitmap(icon, null, icon_dest, p); //[1]
p.setTextSize(50);
p.setColor(Color.WHITE);
c.drawText("Cancel",*/Insert x and y here*/,p);
So far I have that.
I'm trying to drawText directly under the bitmap I drawed. ([1]). However I'm not sure how to get the coordinates of the bitmap and adjust it so that it's centered below it.
The above image is what I'm trying to achieve. Contents of the app has been censored.
In conclusion, how do I get the coordinates for the text that I'm trying to get?
I'm using onChildDraw method of the ItemTouchHelper for a RecyclerView.
You can use paint.getTextBounds() to get the bounds of the text that you are about to draw on the canvas. Once you get the bounds of the text, you can calculate the position to draw the text based on the icon's position.
Edit:
This aligns the text below the icon at the X position same as the icon:
float textX = icon_dest.left;
float textY = icon_dest.bottom + some_padding;
canvas.drawText("Cancel", textX, textY, textPaint);
This aligns the center of the icon and the center of the text in a same vertical line:
Rect textBounds = new Rect();
textPaint.getTextBounds("Cancel", 0, length, textBounds);
float iconCenterX = icon_dest.left + (icon_dest.width() / 2);
float textHalfWidth = (textBounds.right - textBounds.left) / 2;
float textX = iconCenterX - textHalfWidth;
float textY = icon_dest.bottom + somePadding
canvas.drawText("Cancel", textX, textY, textPaint);

drawRoundRect in Android not working

I want to draw a rounded rectangle with drawRoundRect method in Android.
void drawRoundRect (RectF rect, float rx, float ry, Paint paint)
I'm using Android Studio, and my testing device use Android 6.0.1, API 23
This is part of my code. It works find when I put zeros in rx and ry.
public void draw(Canvas canvas){
canvas.drawColor(Color.WHITE);
canvas.drawRoundRect(rect, 0, 0, pnt);
}
This draws a black rectangle in my screen.
But when I try to make it rounded,
public void draw(Canvas canvas){
canvas.drawColor(Color.WHITE);
canvas.drawRoundRect(rect, 10, 10, pnt);
}
It draws nothing. This only draws white background....
I tried different numbers like 100, 3, 5, 0.03f etc in rx and ry,
but any numbers bigger than 0 make drawRoundRect() not working.
Is there anything wrong with my code...?
Make sure that coordinates in RectF that is used to draw rounded rectangle are correct. That means: rect.left < rect.right and rect.top < rect.bottom.
It seems that Android 7 corrects wrong coordinates itself and draws desired rounded rectangle, but Android 6 is drawing nothing if there is problem with coordinates.
you can try this we have a little calculation but it works awesomely
private void drawRoundedRect(Canvas canvas, float left, float top, float right, float bottom) {
float radius = getHeight() / 2;
canvas.drawCircle(radius, radius, radius, mainPaint);
canvas.drawCircle(right - radius, radius, radius, mainPaint);
canvas.drawRect(left + radius, top, right - radius, bottom, mainPaint);
}
or you can check this
RectF rect = new RectF(10,10,20,20);
canvas.drawRoundRect(rect , 0, 0, mPaint);
Try this,
Bitmap bitmap = Bitmap.createBitmap(
600, // Width
300, // Height
Bitmap.Config.ARGB_8888 // Config
);
Canvas canvas = new Canvas(bitmap);
canvas.drawColor(Color.WHITE);
Paint paint = new Paint();
paint.setStyle(Paint.Style.FILL);
paint.setColor(Color.RED);
paint.setAntiAlias(true);
int offset = 50;
RectF rectF = new RectF(
offset, // left
offset, // top
canvas.getWidth() - offset, // right
canvas.getHeight() - offset // bottom
);
int cornersRadius = 25;
canvas.drawRoundRect(
rectF, // rect
cornersRadius, // rx
cornersRadius, // ry
paint // Paint
);
mImageView.setImageBitmap(bitmap);
You could do this,
RectF rect = new RectF(0f, 0f, width, height);
canvas.drawRoundRect(rect , 0, 0, mPaint);

The Projection Matrix Does More than Scaling, Right?

As I have it understood, a projection matrix scales a polygon depending on how far away or close it is from the camera. Though I might be completely wrong. My question is, how does the projection matrix "know" to show the sides of the following cube, as the camera moves, when the matrix is only supposed "scale" polygons?
Notice in the image, the cube is off to the right side of the screen, by moving the camera to the left. If the camera is moved in the opposite direction (to the right) in order to center the cube, the side of the cube will disappear as expected.
Here is my matrix code:
private void createProjectionMatrix(){
float aspectRatio = (float) Display.getWidth() / (float) Display.getHeight();
float y_scale = (float) ((1f / Math.tan(Math.toRadians(FOV/2f))) * aspectRatio);
float x_scale = y_scale / aspectRatio;
float frustum_length = FAR_PLANE - NEAR_PLANE;
projectionMatrix = new Matrix4f();
projectionMatrix.m00 = x_scale;
projectionMatrix.m11 = y_scale;
projectionMatrix.m22 = -((FAR_PLANE + NEAR_PLANE) / frustum_length);
projectionMatrix.m23 = -1;
projectionMatrix.m32 = -((2 * NEAR_PLANE * FAR_PLANE) / frustum_length);
projectionMatrix.m33 = 0;
}
The function of a projection matrix (in the context of graphics APIs, such as OpenGL) is to transform vertex positions from view-space into clip-space.
Clip space is generally a unit box (although in D3D it's a half-unit box). If a vertex position after being transformed into clip-space does not lie within that unit box, then it is clipped. This is essentially how the system "knows" the cube is visible on the screen.

Rotate an opengl shape as box2d body rotates

I have a simple Java app setup which uses JOGL and JBox2D.
Below is how the app renders .. 3 Rectangles, 2 are Dynamic and 1 is Static i.e. the ground.
I can move 1 of the Rectangles left, right or by jumping using a KeyListener and adjusting the bodies BodyLinearVelocity accordingly.
But if the Rectangle (which i can move) falls off the other dynamic Rectangle, the graphical representation of the Box2D Body does not rotate correctly.
It looks like the Box2D Body is rotating but the GL2.GL_QUADS remains standing.
See empty space in below pic, I imagine the Rectangle should look like its standing on one of its edges if it rotated correctly?
How can I achieve this mapping between JOGL and JBox2D?
public class Level extends org.jbox2d.dynamics.World {
private Vector<Rectangle> levelObjects = new Vector<Rectangle>();
public Level(Vec2 gravity) {
super(gravity);
this.setGravity(gravity);
levelObjects.add(
new Rectangle(
new Vec2(17.0f, 10.0f),
0.0f,
2.0f,
2.0f,
BodyType.DYNAMIC,
1.0f,
0.8f,
0.3f,
this));
levelObjects.add(
new Rectangle(
new Vec2(22.0f, 10.0f),
0.0f,
2.0f,
2.0f,
BodyType.DYNAMIC,
1.0f,
0.8f,
0.3f,
this));
}
protected void draw(GLAutoDrawable gLDrawable){
gLDrawable.getGL().getGL2().glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT);
for (Rectangle object : levelObjects){
object.draw(gLDrawable);
}
}
}
This is the Rectangle definition:
public class Rectangle {
private Vec2 centerPoint;
private PolygonShape blockShape;
private BodyDef bodydef;
private Body body;
private World world;
private float width;
private float height;
public Rectangle (Vec2 centerPoint,
float angle, float width, float height,
BodyType bt, float density, float friction, float restitution,
World w) {
this.world = w;
this.angle = angle
this.width = width;
this.height = height;
blockShape = new PolygonShape();
blockShape.setAsBox(this.width, this.height);
FixtureDef fixtureDef = new FixtureDef();
fixtureDef.shape = blockShape;
fixtureDef.density = density;
fixtureDef.friction = friction;
fixtureDef.restitution = restitution;
bodydef = new BodyDef();
bodydef.type = BodyType.DYNAMIC;
bodydef.position.set(this.centerPoint.x, this.centerPoint.y);
body = world.createBody(bodydef);
body.createFixture(fixtureDef);
body.setType(bt);
};
void draw(GLAutoDrawable gLDrawable){
gLDrawable.getGL().getGL2().glLoadIdentity();
gLDrawable.getGL().getGL2().glColor3f(0.0f, 60.0f, 120.0f);
gLDrawable.getGL().getGL2().glTranslatef(this.body.getPosition().x, this.body.getPosition().y, -6.0f);
gLDrawable.getGL().getGL2().glRotatef(this.body.getAngle(), 0, 1, 0);
gLDrawable.getGL().getGL2().glBegin(GL2.GL_QUADS);
gLDrawable.getGL().getGL2().glTexCoord2f(0.0f, 0.0f);
gLDrawable.getGL().getGL2().glVertex3f(-this.width, -this.height, 0.0f);
gLDrawable.getGL().getGL2().glTexCoord2f(0.0f, 1.0f);
gLDrawable.getGL().getGL2().glVertex3f(-this.width, this.height, 0.0f);
gLDrawable.getGL().getGL2().glTexCoord2f(1.0f, 1.0f);
gLDrawable.getGL().getGL2().glVertex3f(this.width, this.height, 0.0f);
gLDrawable.getGL().getGL2().glTexCoord2f(1.0f, 0.0f);
gLDrawable.getGL().getGL2().glVertex3f(this.width, -this.height, 0.0f);
gLDrawable.getGL().getGL2().glEnd();
gLDrawable.getGL().getGL2().glFlush();
}
}
glRotatef takes an angle in degrees in input and you should ensure that your rotation axis is correctly oriented and normalized. I advise you to ask the questions about JOGL on our official forum.
this.body.getAngle() returned angle in radians, so i converted to degrees and rotated on Z-axis.
It works now ..
gLDrawable.getGL().getGL2().glTranslatef(this.body.getPosition().x, this.body.getPosition().y, -6.0f);
gLDrawable.getGL().getGL2().glRotated(Math.toDegrees(this.body.getAngle()), 0, 0, 1);
gLDrawable.getGL().getGL2().glBegin(GL2.GL_QUADS);
gLDrawable.getGL().getGL2().glTexCoord2f(0.0f, 0.0f);
gLDrawable.getGL().getGL2().glVertex3f(-this.width, -this.height, 0.0f);
gLDrawable.getGL().getGL2().glTexCoord2f(0.0f, 1.0f);
gLDrawable.getGL().getGL2().glVertex3f(-this.width, this.height, 0.0f);
gLDrawable.getGL().getGL2().glTexCoord2f(1.0f, 1.0f);
gLDrawable.getGL().getGL2().glVertex3f(this.width, this.height, 0.0f);
gLDrawable.getGL().getGL2().glTexCoord2f(1.0f, 0.0f);
gLDrawable.getGL().getGL2().glVertex3f(this.width, -this.height, 0.0f);
gLDrawable.getGL().getGL2().glEnd();
gLDrawable.getGL().getGL2().glFlush();

libgdx rectangle around actor

How does one draw a Rectangle around an Actor with a given Texture? The Rectangle should scale, move and rotate along with the Actor.
Current implementation:
shapeRenderer.begin(ShapeType.Line);
shapeRenderer.setColor(Color.RED);
Vector2 _BL = localToStageCoordinates(new Vector2(getX(), getY()));
Vector2 _BR = localToStageCoordinates(new Vector2(getX() + getWidth(), getY()));
Vector2 _TL = localToStageCoordinates(new Vector2(getX(), getY() + getHeight()));
Vector2 _TR = localToStageCoordinates(new Vector2(getX() + getWidth(), getY() + getHeight()));
float xmin = MyMathUtils.min(_BL.x, _BR.x, _TL.x, _TR.x);
float ymin = MyMathUtils.min(_BL.y, _BR.y, _TL.y, _TR.y);
float xmax = MyMathUtils.max(_BL.x, _BR.x, _TL.x, _TR.x);
float ymax = MyMathUtils.max(_BL.y, _BR.y, _TL.y, _TR.y);
shapeRenderer.rect(xmin, ymin, xmax-xmin, ymax-ymin);
shapeRenderer.setColor(Color.BLUE);
shapeRenderer.circle(_BL.x, _BL.y, 2);
shapeRenderer.circle(_BR.x, _BR.y, 2);
shapeRenderer.circle(_TL.x, _TL.y, 2);
shapeRenderer.circle(_TR.x, _TR.y, 2);
shapeRenderer.end();
The problem is that Rectangle doesn't fit well after moving the Actor. I think it has to do with a bad Coordinate Transformation.
I would like to do something like this:
Matix4 m = actor.computeTransform();
shapeRenderer.setTransformMatrix(m);
but the computeTransform() is available in Group (which is an Actor), but not in Actor itself.

Categories

Resources