How to scale tiledDrawable in libgdx? - java

Here i'm load texture and make textureregion and TiledDrawable instances:
textures = new Texture(Gdx.files.internal("somefile.png"));
bg_grass_region = new TextureRegion(textures, 631, 175, 116, 662);
bg_grass_tiled = new TiledDrawable(bg_grass_sprite);
and inside render method of Screen instance i draw it like this:
batch.begin();
bg_grass_tiled.draw(batch, 0, 0, bg_grass_sprite.getWidth(), bg_grass_sprite.getHeight()*3);
batch.end();
The problem is that bg_grass_region is TextureRegion instance, and it complitly won't to scale...
So, i have a one simple question: How to scale/resize bg_grass_tiled or bg_grass_region objects?

TiledDrawable draws a TextureRegion repeatedly to fill the area, instead of stretching it. Implemented by TransformDrawable, however It not support scaling and rotation.
so you can't use below method of TiledDrawable, it throws UnsupportedOperationException
draw (Batch batch, float x, float y, float originX, float originY, float width, float height, float scaleX,float scaleY, float rotation)
Why don't you use draw method of SpriteBatch with TextureRegion.
draw (TextureRegion region, float x, float y, float originX, float originY, float width, float height,float scaleX, float scaleY, float rotation);

Related

Center rectangle-object in the screen by using glOrthof in Android with opengles 2, with java

I'm working on the examples of the book OpenGlEs 2 for Android.
I did the first example, for drawing a rectangle of base 9, and height 14, by using the below array for defining the coordinates
private float[] tableVerticesWithTriangles = {
//Triangle
0f, 0f,
9f, 14f,
0f, 14f,
//Triangle 2
0f, 0f,
9f, 0f,
9f, 14f
};
The rectangle is appearing as in the example, the white rectangle in the top right corner:
The code I'm working on is in the repository https://github.com/quimperval/opengles-android-rectangle
Now in the book the author centers the rectangle by modifying the coordinates of the rectangle, however as far as I know, openGl can take care of that by using a projection matrix. So, I modified the vertex shader for using a projection Matrix
attribute vec4 a_Position;
attribute mat4 u_Projection;
void main(){
gl_Position = u_Projection * a_Position;
}
And in the CRenderer class I added the below variables
private static final String U_PROJECTION = "u_Projection";
int projectionMatrixLocation;
and the
float[] projectionMatrix = new float[16];
And in the onSurfaceChanged method I added the logic for considering the aspectRatio
#Override
public void onSurfaceChanged(GL10 gl10, int width, int height) {
glViewport(0, 0, width, height);
// Calculate the projection matrix
float aspectRatio = width > height ?
(float) width / (float) height :
(float) height / (float) width;
if (width > height) {
// Landscape
glOrthof(-aspectRatio, aspectRatio, -1f, 1f, -1f, 1f);
} else {
// Portrait or square
glOrthof(-1f, 1f, -aspectRatio, aspectRatio, -1f, 1f);
}
projectionMatrixLocation = glGetUniformLocation(program, "u_Projection");
glUniformMatrix4fv(projectionMatrixLocation, 1, false, projectionMatrix, 0);
}
In the onDrawFrame I didn't do changes.
When I compile and install the application in the emulator, It crashes, with the error:
2022-12-31 14:45:23.971 10499-10521/com.perval.myapplication A/libc: Fatal signal 11 (SIGSEGV), code 1, fault addr 0x0 in tid 10521 (GLThread 411)
Am I missing some operation?
I expect to center the rectangle (of any dimensions) in the screen of the device.
I believe the answer is that you are:
Not declaring the matrix as a uniform
Not checking your response from glGetUniformLocation()
As you are accessing a uniform with glGetUniformLocation, you should declare it in your shader like so:
uniform mat4 u_Projection;
I manage to find another way to achive the result I need, by using the below code in the onSurfaceChangedMethod
#Override
public void onSurfaceChanged(GL10 gl10, int width, int height) {
glViewport(0,0, width, height);
/*orthoM
*projectionMarix - float[] m - the destination array
* mOffset - the offset in to m which the result is written
* float left - the minimum range of the x-axis
* float right - the maximum range of the x-axis
* float bottom - the minimum range of the y-axis
* float top - the maximum range ot the y-axis
* float near - the minimum range of the z-axis
* float far - the maximum range of the z-axis
*
*/
float boundingBoxWidth = 300;
float boundingBoxHeight = 300;
float aspectRatio;
if(width>height){
//Landscape
aspectRatio = (float) width / (float) height;
orthoM(projectionMatrix, 0, -aspectRatio*boundingBoxHeight, aspectRatio*boundingBoxHeight, -boundingBoxHeight, boundingBoxHeight, -1f, 1f);
} else {
//Portrait or square
aspectRatio = (float) height / (float) width;
orthoM(projectionMatrix, 0, -boundingBoxWidth, boundingBoxWidth, -boundingBoxWidth*aspectRatio, boundingBoxWidth*aspectRatio, -1f, 1f);
}
}
In that way I got the behaviour I wanted, place an object in the center of the screen, and the object has vertex coordinates outside of the surface extents (-1,-1) to (1,1).
The key is to know the width and the height of the collision box of the object I want to draw, then it is just a matter of scaling the left, right or bottom/top variables based on the orientation of the screen, with the aspectRatio variable.
I placed the code in the repository:
https://github.com/quimperval/opengl-es-android-draw-object

Explanation on libgdx draw method

I am learning libgdx, I have passed around some of tutorials but I always face problems understanding the batch.draw() method
public void draw(Texture texture,
float x,
float y,
float originX,
float originY,
float width,
float height,
float scaleX,
float scaleY,
float rotation,
int srcX,
int srcY,
int srcWidth,
int srcHeight,
boolean flipX,
boolean flipY)
I read its documentation and still got confused of the following statement:-
The rectangle is offset by originX, originY relative to the origin.
WHAT DOES THIS MEAN?. Which origin are talking about here?
Also i did a simple sketch of what I visual understand the draw() method. Am I on the right path?
Thanks.
The rectangle is offset by originX, originY relative to the origin.
Scaling and Rotation performed around originX, originY.
batch.begin();
batch.draw(texture,300,200,50,50,100,100,1,1,0,100,100,50,50,false,false);
batch.end();
And Output is
Now rotate by 90 degree :
batch.draw(texture,300,200,50,50,100,100,1,1,90,100,100,50,50,false,false);
so rectangle offseted around centre by 90 degree
originX and originY is in the center of Rectangle so no offset appears in x,y
Let's put originX and originY at left bottom of rectangle and rotate by 90 degree
batch.draw(texture,300,200,0,0,100,100,1,1,90,100,100,50,50,false,false);

Why isn't this a square? LWJGL

I have a basic LWJGL window set up and I am trying to draw a square using the glBegin(GL_QUADS) method. Square square = new Square(25, 25, 25), is the way I am calling my Square class to draw the square... but it is a rectangle. When I call it I pass in all 25's as the parameters. the first two are the starting coordinates and the last 25 is the side length, as seen below. What am I doing wrong to produce a rectangle?
public Square(float x,float y,float sl) {
GL11.glColor3f(0.5F, 0.0F, 0.7F);
glBegin(GL11.GL_QUADS);
glVertex2f(x, y);
glVertex2f(x, y+sl);
glVertex2f(x+sl, y+sl);
glVertex2f(x+sl, y);
glEnd();
}
My Viewport code
glMatrixMode(GL_PROJECTION);
glLoadIdentity(); // Resets any previous projection matrices
glOrtho(0, 640, 0, 480, 1, -1);
glMatrixMode(GL_MODELVIEW);
Using glOrtho(0, 640, 0, 480, 1, -1); constructs a non-square viewport. That means that the rendered output is more than likely going to be skewed if your window is not the same size as your viewport (or at least the same aspect ratio).
Consider the following comparison:
If your viewport is the same size as your window, then it should remain square. I'm using JOGL, but in my resize function, I reshape my viewport to be the new size of my window.
glcanvas.addGLEventListener(new GLEventListener() {
#Override
public void reshape(GLAutoDrawable glautodrawable, int x, int y, int width, int height) {
GL2 gl = glautodrawable.getGL().getGL2();
gl.glMatrixMode(GL2.GL_PROJECTION);
gl.glLoadIdentity(); // Resets any previous projection matrices
gl.glOrtho(0, width, 0, height, 1, -1);
gl.glMatrixMode(GL2.GL_MODELVIEW);
}
... Other methods
}
To draw a square around the point (x | y) you can calculate the four points that represent the corners of your square.
First you'll need your width to height ratio
float ratio = width / height
I will use a defaultSize for the length of the shortest path from the midpoint to any of the sides.
Then you can calculate four values like so:
float a = x + defaultSize
float b = ratio * (y + defaultSize)
float c = x - defaultSize
float d = ratio * (y - defaultSize)
with which you can represent all four corners to draw your square with. Since GL_SQUAD is deprecated I'll use GL_TRIANGLE.
glBegin(GL_TRIANGLES);
glColor3f(red, green, blue);
// upper left triangle
glVertex2f(a, b);
glVertex2f(c, b);
glVertex2f(c, d);
// lower right triangle
glVertex2f(a, b);
glVertex2f(c, d);
glVertex2f(a, d);
glEnd();
I don't know if this is the most performant or idiomatic way to do this since I just started exploring LWJGL.

Java Canvas - Rectangle2D Scales when Moving

I am drawing a series of rectangles on a Canvas. The rectangles are supposed to move on an angle. For some reason, when they move, they scale up:
xPos += xSpeed;
yPos += ySpeed;
updateBounds(xPos, yPos, width, height);
My UpdateBounds method:
public void updateBounds(double x, double y, double w, double h) {
bounds.setRect(x, y, w, h);
}
Bounds is a Rectangle2D object.
And my Drawing method:
g.fillRect((int) bounds.getX(), (int) bounds.getY(),
(int) bounds.getMaxX(), (int) bounds.getMaxY());
Why am I getting this behaviour?
Graphics.fillRect() accepts a width and height parameter, not the largest x and y position of the rectangle to draw.
The third and fourth parameters to fillRect should be Rectangle2D's getWidth() and getHeight().
As a reference, a link to what getMaxX() would give you.

How to rotate a series of lines and shapes drawn in drawing Panel?

I am wondering how to rotate things I have already drawn (like lines) in Java drawing Panel (not in JPanel).
I am trying to rotate a triangle i created by connecting 3 lines:
g.drawLine(size, size, 2*size, size);
g.drawLine(size, size,size+size/2, size+(int)(size/2 * Math.sqrt(3)));
g.drawLine(2*size, size,size+size/2, size+(int)(size/2 * Math.sqrt(3)));
How do I rotate that?
If you want to rotate a point like that, then you could:
double startX; // <------------|
double startY; // <------------|
double endX; // <------------|
double endY; // <-define these
double angle; // the angle of rotation in degrees
To draw the original line
g.setColor(Color.BLACK);
g.drawLine(startX, startY, endX, endY); //this is the original line
double length = Math.pow(Math.pow(startX-endX,2)+Math.pow(startY-endY,2),0.5);
double xChange = length * cos(Math.toRadians(angle));
double yChange = length * sin(Math.toRadians(angle));
To draw the new, rotated line
g.setColor(Color.GRAY);
g.fillRect(0,0,1000,1000); //paint over it
g.setColor(Color.BLACK);
g.drawLine(startX, startY, endX + xChange, endY + yChange);
Use graphics2D and Polygons
Graphics2D g2 = (Graphics2D) g;
int x2Points[] = {0, 100, 0, 100}; //these are the X coordinates
int y2Points[] = {0, 50, 50, 0}; //these are the Y coordinates
GeneralPath polyline =
new GeneralPath(GeneralPath.WIND_EVEN_ODD, x2Points.length);
polyline.moveTo (x2Points[0], y2Points[0]);
for (int index = 1; index < x2Points.length; index++) {
polyline.lineTo(x2Points[index], y2Points[index]);
};
g2.draw(polyline);
If you want to rotate it, just do it over but add, before
g2.rotate(Math.toRadians(angle), centerX, centerY);
Where "angle" is the amount you want to rotate it and (centerX, centerY) are the coordinates of the point you want to rotate it around.
I hope this helps

Categories