I am trying to draw an circle to Libgdx which is created from Image not ShapeRenderer. But when I try to draw image to SpriteBatch it does not draw smoothly.
I checked the image resolution and Image Dimension is 1673x1673 and Sprite Size is 80x80.
//This is my GameState code
#Override
public void render(float delta) {
update(delta);
SpriteBatch sb = game.batch;
Color bg = ThemeFactory.getInstance().getTheme().backgroundColor;
Gdx.gl.glClearColor(bg.r, bg.g, bg.b, bg.a);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
sb.setProjectionMatrix(camera.combined);
sb.begin();
for(int i =0;i<elements.size();i++){
if(!(elements.get(i) instanceof Arrow)){
elements.get(i).render(sb);//HERE IS DRAWING HAPPENING
}
}
sb.end();
barriers.render(sb);
renderHud();
}
My circle constructor and rendering code is below.
public Circle(Texture texture, Size size, Vector3 position){
mSprite = new Sprite(texture);
mSprite.setSize(size.width, size.height);//80x80
mSprite.setPosition(position.x, position.y);
mSprite.setOriginCenter();
}
#Override
public void render(SpriteBatch sb) {
mSprite.draw(sb);
}
2 tips:
1. Raise up sampling
2. use libgdx mipmap for your texture
I recommend using : filter 1: MipMapLinearNearest,Nearest or filter 2: Linear,Linear
filter 1 is fast, filter 2 is high quality
for more info read this
Filtering
The minification/magnification filters define how the image is handled upon scaling. For "pixel-art" style games, generally Filter.Nearest is suitable as it leads to hard-edge scaling without blurring. Specifying Filter.Linear will use bilinear scaling for smoother results, which is generally effective for 3D games (e.g. a 1024x1024 rock or grass texture) but not always so for a 2D game. In OpenGL, the terms used are GL_NEAREST and GL_LINEAR, respectively.
Use filter in your texture.
Eg.
texture.setFilter (TextureFilter.Nearest, TextureFilter.Nearest );
For more information about filters, refer this blog: http://www.badlogicgames.com/wordpress/?p=1403
Related
When I draw more around 100-200 textures all in the same screen, the device becomes very slow and the app crashes without any exceptions. Could you please let me know any best way to have 100 textures without compromising the performance.
I am using the TextureRegion from TextureAtlas.
MainGame
public void render(SpriteBatch sb) {
// TODO Auto-generated method stub
// System.out.println("BallPoolGame Screen - render");
batch = sb;
sb.setProjectionMatrix(camera.combined);
sb.begin();
sb.draw(BACKGROUND_BALL_POOL, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT);
cellManager.draw(sb);
ballManager.draw(sb);
sb.end();
}
private void setGameTextures() {
gameScreenAtlas = new TextureAtlas("data/texturetutorialpack.pack");
RED_BALL = gameScreenAtlas.findRegion("redball");
// RED_BALL.getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
BLUE_BALL = gameScreenAtlas.findRegion("blueball");
// BLUE_BALL.getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
GREEN_BALL = gameScreenAtlas.findRegion("greenball");
// GREEN_BALL.getTexture().setFilter(TextureFilter.Linear, TextureFilter.Linear);
}
CellManager
public void draw(SpriteBatch sb){
batch=sb;
showImageTexture(MODEL1,207,1);
if(showSelectedCell){
if(allPossiblePathSize>0)
setupBoardCellTexture();
showImage(CELL_SELECTED, rowCoordinate[cellRow], colCoordinate[cellCol]);
}
}
private void setupBoardCellTexture(){
for(CellGrid c : masterGrid){
if(cellTextureIndicator[c.getRow()][c.getCol()]==1){
showImage(CELL_ALL_PATH_TEXTURE,c.getRowCoordinate() ,c.getColCoordinate() );
}
}
}
private void showImage(TextureRegion tr, float rowCoordinate, float colCoordinate) {
batch.draw(tr, colCoordinate,rowCoordinate);
}
BallManager
public void draw(SpriteBatch sb) {
batch = sb;
setupBoardBallTexture();
if (moveTheBall) {
updateBallPosition();
showImage(ball.getTextureRegion(), moveRow + 6, moveCol + 6);
}
squeezeBalls.draw(sb);
}
You are missing some essential data about your app to answer than question:
How big is one texture on average (Size: widthxheight)
On which device is this error occuring (some devices might have less fillrate than others)
What texture filter does the TextureAtlas use (LINEAR, NEAREST, ...)
I guess that you are trying to draw many textures event if they are out of sight. If that is the case you have to implement a check if the cell is visible to the camera.
Another guess would be that you are trying to draw too many elements with the LINEAR TextureFilter. When using linear as a texture filter the gpu needs to sample way more points then with nearest (i think it was 4 times the samples; so in theory your gpu draws 400-800 textures; depending on images size that are too much for mobile gpu fillrates)
Try to describe more circumstances then i can give probably more insight in your problem.
I have a custom View and two Bitmaps. I draw the one above the other like this
canvas.drawBitmap(backImage,0,0,null);
canvas.drawBitmap(frontImage,0,0,null);
Before painting I set some pixels in the frontImage transparent using the setPixel(...) function of Bitmap
frontImage.setPixel(x,y, Color.TRANSPARENT);
Instead of viewing backImage's pixels at x,y I see black color...
There may be a really simple solution to this. What is your source material for the images? If you are loading them from files all you may need to do is convert the source files to PNG's. PNG's maintain transparency information and most rendering engines will take this in to account when layering them together on the screen.
Another Possibility. I use this technique quite a bit in Java games on the PC. It uses a little transparency class I stumbled across a number of years ago at this location:
/*************************************************************************
* The Transparency class was also developed by a thrid party. Info
* on its use can be found at:
*
* http://www.rgagnon.com/javadetails/java-0265.html
*
*************************************************************************/
//Transparency is a "Static", "Inner" class that will set a given color
//as transparent in a given image.
class Transparency {
public static Image set(Image im, final Color color) {
ImageFilter filter = new RGBImageFilter() { //Inner - Inner class -- very bad
// the color we are looking for... Alpha bits are set to opaque
public int markerRGB = color.getRGB() | 0xFF000000;
public final int filterRGB(int x, int y, int rgb) {
if ( ( rgb | 0xFF000000 ) == markerRGB ) {
// Mark the alpha bits as zero - transparent
return 0x00FFFFFF & rgb;
}
else {
// nothing to do
return rgb;
}
}
};
//apply the filter created above to the image
ImageProducer ip = new FilteredImageSource(im.getSource(), filter);
return Toolkit.getDefaultToolkit().createImage(ip);
}
}
Taking a Java Image object as input it will take what ever color you give it and perform the math on the image turning the color transparent.
Good luck.
I am making a game with libgdx. if i touch the screen then a texture appears, but what i really want to do is that when i touch a specific texture then the other texture must appear.
this is my code for now:
public class MyGame extends InputAdapter implements ApplicationListener {
SpriteBatch batch;
Texture ball;
Texture bat;
#Override
public void create() {
ball = new Texture("ball.png");
bat = new Texture("bat.png");
batch = new SpriteBatch();
}
#Override
public void render() {
batch.begin();
if (Gdx.input.isTouched()) {
batch.draw(ball, Gdx.input.getX(), Gdx.graphics.getHeight()
- Gdx.input.getY());
batch.draw(bat, 50, 50);
batch.end();
}
}
}
it's not the whole code, just the code that is used to appear those textures.
I really appreciate your help.
Thankyou
The code below gives an example of how you can extend your current approach to test if the touch is within the area of your texture, but I would not recommend it for use in a real game.
It is fine as an exercise to understand what is going on, but manually coding the touch regions in this way will quickly become cumbersome as your game becomes more complex.
I would strongly recommend you become familiar with the scene2d package in libGdx. This package has methods to handle all the common 2D behaviors such as touch events, movement and collisions.
Like a lot of the libGdx library, the documentation can be hard to follow if you're just starting out, and there are not many tutorials around either. I'd recommend working through the Java Game Development (LibGDX) series of youtube videos by dermetfan. It helped me understand many areas when I was starting out. Good luck.
SpriteBatch batch;
Texture firstTexture;
Texture secondTexture;
float firstTextureX;
float firstTextureY;
float secondTextureX;
float secondTextureY;
float touchX;
float touchY;
#Override
public void create() {
firstTexture= new Texture("texture1.png");
firstTextureX = 50;
firstTextureY = 50;
secondTexture = new Texture("texture2.png");
secondTextureX = 250;
secondTextureY = 250;
batch = new SpriteBatch();
}
#Override
public void render() {
batch.begin; // begin the batch
// draw our first texture
batch.draw(firstTexture, firstTextureX, firstTextureY);
// is the screen touched?
if (Gdx.input.isTouched()) {
// is the touch within the area of our first texture?
if (touchX > firstTextureX && touchX < (firstTextureX + firstTexture.getWidth())
&& touchY > firstTextureY && touchY < (firstTextureY + firstTexture.getHeight()) {
// the touch is within our first texture so we draw our second texture
batch.draw(secondTexture, secondTextureX, secondTextureY);
}
batch.end; // end the batch
}
I am having problems with dynamic loading of textures.
When a user double taps on the screen, the background and other sprites are changed. There is no error produced, but some times the textures are cleared and new textures are just not loaded.
This is my initial onCreateResource
ITextureRegion BackgroundTextureRegion;
BitmapTextureAtlas MainTexture1;
//Initiate Textures
MainTexture1 = new BitmapTextureAtlas(this.getTextureManager(),1000,1000, TextureOptions.BILINEAR);
//Clear Textures
MainTexture1.addEmptyTextureAtlasSource(0, 0, 1000,1000);
//Assign Image Files to TextureRegions
BackgroundTextureRegion = BitmapTextureAtlasTextureRegionFactory.createFromAsset(MainTexture1, this, "Evening.jpg",0,0);
//Loading the Main Texture to memory
MainTexture1.load();
There is no problem until after this point. After this when user double taps or swipes the background, I change the texture dynamically. Here is the code:
MainTexture1.clearTextureAtlasSources();
MainTexture1.addEmptyTextureAtlasSource(0, 0, 1000,1000);
BitmapTextureAtlasTextureRegionFactory.createFromAsset(MainTexture1, this, "WinterNight.jpg",0,0);
This usually changes the texture and I am getting the desired result. But in some devices (eg. Samsung Tab 2), 1 in 10 times the the MainTexture1 is cleared but its not loaded with new image.
So it just gives a black screen, how do I correct this?
MainTexture1.clearTextureAtlasSources();
// MainTexture1.addEmptyTextureAtlasSource(0, 0, 1000,1000);
BitmapTextureAtlasTextureRegionFactory.createFromAsset(MainTexture1, this, "WinterNight.jpg",0,0);
MainTexture1.load();
Try this
runOnUiThread(new Runnable() {
#Override
public void run() {
MainTexture1.clearTextureAtlasSources();
MainTexture1.addEmptyTextureAtlasSource(0, 0, 1024, 1024);
BitmapTextureAtlasTextureRegionFactory.createFromAsset(MainTexture1, this, "WinterNight.jpg",0,0);
MainTexture1.load();
}
});
Like this.
If it is not working try with creating another textureatlas instead of same atlas.
I'm trying to draw a simple rect on the screen in a class and using it as an actor.
But whatever I do, it seems that there is no option to draw it transparent. Does anyone know how to do this?
Thanks in advance!
public class AreaColorRect extends Actor {
public float opacity = 0.0f;
private Color shapeFillColor = new Color();
public Rectangle area;
public ShapeRenderer shapeRen;
public AreaColorRect(float x, float y, float w, float h) {
shapeRen = new ShapeRenderer();
this.area = new Rectangle(x, y, w, h);
}
#Override
public void draw(SpriteBatch batch, float parentAlpha) {
shapeRen.begin(ShapeType.Filled);
shapeRen.setColor(new Color(shapeFillColor.r, shapeFillColor.g, shapeFillColor.b,
0.0f));
shapeRen.rect(area.x, area.y, area.width, area.height);
shapeRen.end();
}
public void setShapeFillColor(float r, float g, float b) {
this.shapeFillColor = new Color(r, g, b, 1);
}
}
You're mixing contexts. End your SpriteBatch before starting the ShapeRenderer. See libgdx - ShapeRenderer in Group.draw renders in wrong colour. This might not be the problem, though.
You also need to turn on blending. You can just do this once globally, or enable it as necessary (and disable it). It should be enabled by the SpriteBatch context, but I don't think its enabled for the ShapeRenderer.
Gdx.graphics.getGL10().glEnable(GL10.GL_BLEND); // Or GL20
The order you render your background and Actors also makes a difference for transparency.
Finally, you've set the opacity to 0, so the object will be completely invisible. That generally doesn't do anything at all. (I assume you're just trying to get a change from the current 100% visible?)
Sorry for digging this up. Since you are tagging Android, though, I thought I would just chip in my experiences.
I recently spent almost 4 hours on a problem, where alpha blending just wasn't working, as it isn't for you.
Turned out that libgdx' AndroidApplicationConfiguration uses 0 bit for alpha channel as default.
If this is the case for you, too, it might be worth changing that to something more sensible before you initialize() your app.
I just decided to use Scene2d for my game and reached the same question: how to use a rectangle as an actor and draw it on the screen?
Then i found this piece of documentation on the libgdx wiki
(By default the Scene2d has a SpriteBatch that handles drawing of the actors)
If an actor needs to perform drawing differently, such as with a
ShapeRenderer, the Batch should be ended and then begun again at the
end of the method. Of course, this causes the batch to be flushed, so
should be used judiciously. The transformation and projection matrices
from the Batch can be used:
private ShapeRenderer renderer = new ShapeRenderer();
public void draw (Batch batch, float parentAlpha) {
batch.end();
renderer.setProjectionMatrix(batch.getProjectionMatrix());
renderer.setTransformMatrix(batch.getTransformMatrix());
renderer.translate(getX(), getY(), 0);
renderer.begin(ShapeType.Filled);
renderer.setColor(Color.BLUE);
renderer.rect(0, 0, getWidth(), getHeight());
renderer.end();
batch.begin();
}