How do I create Pixmap from TextureRegion or from Sprite? I need this in order to change color of some pixels and then create new Texture from Pixmap (during loading screen).
Texture texture = textureRegion.getTexture();
if (!texture.getTextureData().isPrepared()) {
texture.getTextureData().prepare();
}
Pixmap pixmap = texture.getTextureData().consumePixmap();
If you want only a part of that texture (the region), then you'll have to do some manual processing:
for (int x = 0; x < textureRegion.getRegionWidth(); x++) {
for (int y = 0; y < textureRegion.getRegionHeight(); y++) {
int colorInt = pixmap.getPixel(textureRegion.getRegionX() + x, textureRegion.getRegionY() + y);
// you could now draw that color at (x, y) of another pixmap of the size (regionWidth, regionHeight)
}
}
If you don't want to walk through the TextureRegion Pixel by Pixel you also can draw the Region onto a new Pixmap
public Pixmap extractPixmapFromTextureRegion(TextureRegion textureRegion) {
TextureData textureData = textureRegion.getTexture().getTextureData()
if (!textureData.isPrepared()) {
textureData.prepare();
}
Pixmap pixmap = new Pixmap(
textureRegion.getRegionWidth(),
textureRegion.getRegionHeight(),
textureData.getFormat()
);
pixmap.drawPixmap(
textureData.consumePixmap(), // The other Pixmap
0, // The target x-coordinate (top left corner)
0, // The target y-coordinate (top left corner)
textureRegion.getRegionX(), // The source x-coordinate (top left corner)
textureRegion.getRegionY(), // The source y-coordinate (top left corner)
textureRegion.getRegionWidth(), // The width of the area from the other Pixmap in pixels
textureRegion.getRegionHeight() // The height of the area from the other Pixmap in pixels
);
return pixmap;
}
Related
I am trying to create a function (ring) that allows me to draw multiple rings around the black circle by only changing the radius, but even when I call it multiple times in draw() it only draws one. I have tried checking if there is something wrong that restricts it to one, but I can't find it. Thank you for your time :)
//VOID
//Set of written numbers
String numbers = "87237462835465598709986654374649";
PFont font;
float r = 40; // Radius of the circle of the written numbers
void setup()
{
size(640, 480);
font = loadFont("AgencyFB-Reg-48.vlw"); //Create futuristic font
textFont(font, 14);
smooth();
}
void draw()
{
background(255);
//Black circle (center of the void)
fill(0);
noStroke();
ellipse(550,80,r*2,r*2);
//FUNCTION for the numbers
ring(40);
}
void ring(float r) {
// Circle for the written numbers
translate(550, 80);
noFill();
noStroke();
ellipse(0, 0, r, r);
// We must keep track of our position along the curve
float arclength = 0;
// For every box
for (int i = 0; i < numbers.length(); i=i+1)
{
// Instead of a constant width, we check the width of each character.
char currentChar = numbers.charAt(i);
float w = textWidth(currentChar);
// Each box is centered so we move half the width
arclength += w/2;
// Angle in radians is the arclength divided by the radius
// Starting on the left side of the circle by adding PI
float theta = PI + arclength / r;
pushMatrix();
// Polar to cartesian coordinate conversion
translate(r*cos(theta), r*sin(theta));
// Rotate the box
rotate(theta+PI/2); // rotation is offset by 90 degrees
// Display the character
fill(0);
text(currentChar,0,0);
popMatrix();
// Move halfway again
arclength += w/2;
}
}
If you call ring() multiple times from draw() your code repeatedly calls translate(). Each one of these calls are additive, so the text just keeps getting further and further away. One way to stop this from happening is to reset it at the bottom of the ring function. This is done by using a reverse sign, e.g., translate(x,y) is changed to translate(-x,-y) at the end of the function to put it back where it was to start with. This change in code will allow you to see multiple rings of text.
float r = 40; // Radius of the circle of the written numbers
String numbers = "87237462835465598709986654374649";
void setup() {
size(400, 400);
smooth();
}
void draw() {
background(255);
fill(0);
noStroke();
ellipse(180, 180, r*2, r*2);
for(int x = 40; x < 100; x+=10){
ring(x);
}
}
void ring(float r) {
translate(180, 180); // Move numbers to location of circle
float arclength = 0;
for (int i = 0; i < numbers.length(); i=i+1) {
char currentChar = numbers.charAt(i);
float w = textWidth(currentChar);
arclength += w/2;
float theta = PI + arclength / r;
pushMatrix();
// Polar to cartesian coordinate conversion
translate(r*cos(theta), r*sin(theta));
// Rotate the box
rotate(theta+PI/2); // rotation is offset by 90 degrees
// Display the character
fill(0);
text(currentChar, 0, 0);
popMatrix();
// Move halfway again
arclength += w/2;
}
translate(-180, -180); // Move it back where it was to start
}
I know that there are many questions related to this, but none are relevant to my problem.
So, I have a TiledMap which has 2 layers for boxes in my game - one for the box graphics and one for the box objects. Now, I want to get the textures of all the boxes because I want to be able to draw them anywhere freely. So I wrote some code to find out which tiles a given rectangle (attained from the object layer of the boxes) is covering (this code works fine). Then, from the graphics layer (TileMapTileLayer), I am accessing the textures in those tiles and drawing them to a single texture using Pixmaps. Finally, I store this texture. However, when I render these textures, they are black. Heres the code -
TiledMapTileLayer boxLayer = (TiledMapTileLayer) (map.getLayers().get(2)); // this is the graphics layer
ArrayList<Vector2> cells;
Texture tex;
Pixmap pmap, pmapScld;
int numCols, numRows, cellNum;
int boxInd = 0;
FileTextureData texData;
StaticTiledMapTile tile;
for(RectangleMapObject boxBody : map.getLayers().get(3).getObjects().getByType(RectangleMapObject.class)) { //object layer
bounds = boxBody.getRectangle();
cells = getOccupiedCells(bounds);
numCols = (int) cells.get(0).x; //I have stored the width and height of the texture
numRows = (int) cells.get(0).y; //in tiles in the first Vector2 of the Array
tex = new Texture(numCols * tileWidthOrg, numRows * tileHeightOrg, Format.RGBA8888);
cellNum = 1;
System.out.println(cells);
for(int i = 0 ; i < numCols ; i++) {
for(int j = 0 ; j < numRows ; j++) {
tile = (StaticTiledMapTile) (boxLayer.getCell((int) cells.get(cellNum).x, (int) cells.get(cellNum).y).getTile());
texData = (FileTextureData) tile.getTextureRegion().getTexture().getTextureData();
texData.prepare();
pmap = texData.consumePixmap();
//pmapScld = new Pixmap(tileWidthScld, tileHeightScld, pmap.getFormat());
//pmapScld.drawPixmap(pmap, 0, pmap.getHeight(), pmap.getWidth(), pmap.getHeight(),
//0, pmapScld.getHeight(), pmapScld.getWidth(), pmapScld.getHeight());
tex.draw(pmap, i * tileWidthOrg, j * tileHeightOrg);
pmap.dispose();
texData.disposePixmap();
//pmapScld.dispose();
cellNum++;
}
}
contactListener.addBox(new GBox(world, tex, bounds, boxInd));
tex.dispose();
boxInd++;
}
The code for rendering these boxes -
for(GBox box : contactListener.boxes) {
box.render(sb);
}
public void render(SpriteBatch sb) {
sb.draw(tex, body.getPosition().x - width / 2, body.getPosition().y - height / 2, width, height);
//System.out.println("rendering box " + index + " at position " + body.getPosition());
}
How do I create a simple rounded rectangle button in libgdx without using images? The button should have a drop shadow and should handle pressed state. I want it to be programmatic to make it easy to change the color, style later, etc.
My understanding of your question was how to create a rounded rectangle within the program without having to pre-generate any images outside of code.
I was in a similar situation a while back and I ended writing the function below which generates a Pixmap rounded rectangle based on the parameters (all units are in pixels). It also works with differing alpha values to allow for opacity (which is why there are two Pixmap objects used).
The resulting Pixmap can then easily be passed to a constructor of a Texture if you find that easier to render with.
public static Pixmap createRoundedRectangle(int width, int height, int cornerRadius, Color color) {
Pixmap pixmap = new Pixmap(width, height, Pixmap.Format.RGBA8888);
Pixmap ret = new Pixmap(width, height, Pixmap.Format.RGBA8888);
pixmap.setColor(color);
pixmap.fillCircle(cornerRadius, cornerRadius, cornerRadius);
pixmap.fillCircle(width - cornerRadius - 1, cornerRadius, cornerRadius);
pixmap.fillCircle(cornerRadius, height - cornerRadius - 1, cornerRadius);
pixmap.fillCircle(width - cornerRadius - 1, height - cornerRadius - 1, cornerRadius);
pixmap.fillRectangle(cornerRadius, 0, width - cornerRadius * 2, height);
pixmap.fillRectangle(0, cornerRadius, width, height - cornerRadius * 2);
ret.setColor(color);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
if (pixmap.getPixel(x, y) != 0) ret.drawPixel(x, y);
}
}
pixmap.dispose();
return ret;
}
Using this function it shouldn't be too difficult to make your own wrapper object (e.g. RoundedRectangle) which would re-draw the image every time one of the parameters was changed and needed to be rendered.
Hi i am new to libgdx and try to build a ludo game.right know i could draw the board but when i try to show dice or any peaces nothing happens I attach game code .
please read and help.
public void create() {
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
batch = new SpriteBatch();
camera = new OrthographicCamera(1, h / w);
boardtexture = new Texture(Gdx.files.internal("data/ludo-boardx2.png"));
boardtexture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
boardsprite = new Sprite(boardtexture);
boardsprite.setSize(1f,
1f * boardsprite.getHeight() / boardsprite.getWidth());
boardsprite.setOrigin(boardsprite.getWidth() / 2,
boardsprite.getHeight() / 2);
boardsprite.setPosition(-boardsprite.getWidth() / 2,
-boardsprite.getHeight() / 2);
Texture dice = new Texture(Gdx.files.internal("data/dices.png"));
dice.setFilter(TextureFilter.Linear, TextureFilter.Linear);
dtemp = new Sprite(dice);
dtemp.setSize(1f, 1f * dtemp.getHeight() / dtemp.getWidth());
dtemp.setPosition(0f, 0f);
// System.out.println(w/2+" " +h/2);
// System.out.println(dtemp.getWidth()+":"+dtemp.getHeight());
// animatedDice.setPosition(new Vector2(0, 0));
System.out.println(animatedDice.getX() + ":" + animatedDice.getY()
+ "\n" + w + ":" + h);
}
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
// camera.update();
handleInput();
batch.begin();
boardsprite.draw(batch);
dtemp.draw(batch);
//animatedDice.draw(batch);
batch.end();
// animatedDice.update();
}
You are drawing your die at a position of (w/2, h/2), which is way out of range of your viewport. You set your viewport so the X coordinate of the right side of your screen is 0.5, but your sprite's left side is at x=w/2, where w is the number of pixels wide your window is.
Even if you had set your camera size to match the window ((w, h)), you would have an issue here because you'd be drawing your sprite so its left edge matched the right edge of the screen. By default, the origin of your die sprite will be its lower left corner.
If you aren't planning to zoom your scene in and out, it might be simpler to set your camera viewport to the size of the window by using camera = new OrthographicCamera(w, h); Then you'll know that your units are equivalent to pixels.
I'm trying to run DFT in 4x4 blocks over this image (look closely, it's small) It may be a bit too small to see, but it's a 4x12 pixel image. The first 4x4 square is a checkerboard pattern with each square having one pixel, the second 4x4 square is the same pattern with each square having two pixels, and the last 4x4 square is a black square.
The problem I have is that the frequency components I get are not what I expect at all. For example, for the first square I expect to have a DC component in the matrix, but it's not there. I figure I must be doing something wrong but I'm new to EMGU so I'm not sure what. Below is my code.
using (Image<Bgr, byte> image = new Image<Bgr, byte>(Openfile.FileName))
using (Image<Gray, float> gray = image.Convert<Gray, float>())
{
int numRectanglesPerRow = image.Width / WIDTH;
int numRectanglesPerColumn = image.Height / HEIGHT;
for (int i = 0; i < numRectanglesPerColumn; i++)
{
for (int j = 0; j < numRectanglesPerRow; j++)
{
Rectangle rectangle = new Rectangle(WIDTH * j, HEIGHT * i, WIDTH, HEIGHT);
Image<Gray, float> subImage = gray.Copy(rectangle);
Matrix<float> dft = new Matrix<float>(subImage.Rows, subImage.Cols, 2);
CvInvoke.cvDFT(subImage, dft, Emgu.CV.CvEnum.CV_DXT.CV_DXT_FORWARD, -1);
//The Real part of the Fourier Transform
Matrix<float> outReal = new Matrix<float>(subImage.Size);
//The imaginary part of the Fourier Transform
Matrix<float> outIm = new Matrix<float>(subImage.Size);
CvInvoke.cvSplit(dft, outReal, outIm, IntPtr.Zero, IntPtr.Zero);
}
}
}