I'm working on a word game and I was dynamically creating the textures for the letter tiles when the game loads, comprising of a background image and a font.
To do this I was drawing pixmaps onto pixmaps, this was all fine until I started working on scaling. The font scaling on the pixmaps was terrible, even with bilinear filtering turned on (left image below) even though my scaled fonts were looking pretty good elsewhere.
So I decided to get round this I'd use a frame buffer, render everything to that and then copy that out to a pixmap and create a texture from that. That way I could use the gpu filtering and it should look exactly the same as my other fonts, (middle image below) but it still didn't look quite as nice as the other fonts. A slight dark line round the outside, it looks like the alpha blending isn't working properly.
I then tried drawing straight over the tiles with the font at runtime to make sure it wasn't my imagination, and this definitely looks better with smooth blending into the image below (right image below), but this impacts my frame rate quite a lot.
So my question is, why is drawing to the frame buffer not producing the same result as when I draw to the screen? Code below.
Texture tx = Assets.loadTexture("bubbles/BubbleBlue.png");
tx.setFilter(TextureFilter.Linear, TextureFilter.Linear);
SpriteBatch sb = new SpriteBatch();
FrameBuffer fb = new FrameBuffer(Format.RGBA8888,
LayoutManager.getWidth(), LayoutManager.getHeight(), false);
fb.begin();
sb.begin();
sb.draw(tx, 0, 0, LetterGrid.blockWidth, LetterGrid.blockHeight);
Assets.candara80.font.getRegion().getTexture()
.setFilter(TextureFilter.Linear, TextureFilter.Linear);
Assets.candara80.setSize(0.15f);
TextBounds textBounds = Assets.candara80.getBounds(letter);
Assets.candara80.drawText(sb, letter,
(LetterGrid.blockWidth - textBounds.width) / 2,
(LetterGrid.blockHeight + textBounds.height) / 2);
sb.end();
Pixmap pm = ScreenUtils.getFrameBufferPixmap(0, 0,
(int) LetterGrid.blockWidth, (int) LetterGrid.blockHeight);
Pixmap flipped = flipPixmap(pm);
result = new Texture(flipped);
fb.end();
pm.dispose();
flipped.dispose();
tx.dispose();
fb.dispose();
sb.dispose();
set PROJECTION is the problem.
EXAMPLE
public Texture texture(Color fg_color, Color bg_color)
{
Pixmap pm = render( fg_color, bg_color );
texture = new Texture(pm);//***here's your new dynamic texture***
disposables.add(texture);//store the texture
}
//---------------------------
public Pixmap render(Color fg_color, Color bg_color)
{
int width = Gdx.graphics.getWidth();
int height = Gdx.graphics.getHeight();
SpriteBatch spriteBatch = new SpriteBatch();
m_fbo = new FrameBuffer(Format.RGB565, (int)(width * m_fboScaler), (int)(height * m_fboScaler), false);
m_fbo.begin();
Gdx.gl.glClearColor(bg_color.r, bg_color.g, bg_color.b, bg_color.a);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
/**set PROJECTION**/
Matrix4 normalProjection = new Matrix4().setToOrtho2D(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
spriteBatch.setProjectionMatrix(normalProjection);
spriteBatch.begin();
spriteBatch.setColor(fg_color);
//do some drawing ***here's where you draw your dynamic texture***
...
spriteBatch.end();//finish write to buffer
pm = ScreenUtils.getFrameBufferPixmap(0, 0, (int) width, (int) height);//write frame buffer to Pixmap
m_fbo.end();
// pm.dispose();
// flipped.dispose();
// tx.dispose();
m_fbo.dispose();
m_fbo = null;
spriteBatch.dispose();
// return texture;
return pm;
}
Related
I am trying to further process a Camera2 image. Because the cameras in devices have different rotations and flipped based on back and front camera, I use transforms to properly rotate it.
transformationMatrix is that matrix for the front camera that has 270 rotation.
Then from that transformed camera image, I want to copy a scrolling window to another bitmap. I want to retain that bitmap/state and draw a line before drawing finalBitmapWithScanner on the phone screen.
Is there a way to do this more efficiently and fast? The second line takes 200ms to complete which is the main issue here.
Canvas canvas = new Canvas(tempBitmap);
canvas.drawBitmap(cameraBitmap, transformationMatrix, paint); // <= 200ms
Rect src = new Rect((int) lastXPos, 0, (int) mXPos, mViewHeight);
Canvas canvas2 = new Canvas(finalBitmap);
canvas2.drawBitmap(tempBitmap, src, src, paint);
Canvas canvas3 = new Canvas(finalBitmapWithScanner);
canvas3.drawBitmap(finalBitmap, 0, 0, paint);
canvas3.drawLine(mXPos, 0, mXPos, mViewHeight/2, scrollerPaint);
transformationMatrix.reset();
transformationMatrix.setRotate(270, imageHeight, 0);
transformationMatrix.postTranslate(-imageHeight, 0);
transformationMatrix.postScale(scaleFactor, scaleFactor);
transformationMatrix.postScale(-1f, 1f, mViewWidth / 2f, mViewHeight / 2f);
There are bunch of ways you can try to achieve fast rendering:
You can pass parameters "paint" an null.
also you can use function CreateScaledBitmap and notice you have to set scale and size before rendering as see in below:
As you can see in documentation enter link description here; you have to resize and rescale your bitmap before rendering so you can use code below for your BitmapFactory.Options :
mBitmapOptions.inScaled = true;
mBitmapOptions.inDensity = srcWidth;
mBitmapOptions.inTargetDensity = dstWidth;
// will load & resize the image to be 1/inSampleSize dimensions
mCurrentBitmap = BitmapFactory.decodeResources(getResources(),
mImageIDs, mBitmapOptions);
use canvas.restore() after draw func.
I'm using libgdx but this is pretty much vanilla opengl es 2.0 stuff. Just try and ignore the Gdx.gl prefix everywhere ^^ I'm testing it on my desktop as well as android device and it's the same story in both cases.
I have the following code in my window resize event. It is supposed to delete the frame buffer and associated textures if they already were created, and then make some new ones the right size. I'm not sure if this is even correct to delete the textures and framebuffer like i am doing.
if (depthTexture >= 0)
{
Gdx.gl.glDeleteTexture(depthTexture);
depthTexture = -1;
}
if (colorTexture >= 0)
{
Gdx.gl.glDeleteTexture(colorTexture);
colorTexture = -1;
}
if (depthBuffer >= 0)
{
Gdx.gl.glDeleteFramebuffer(depthBuffer);
depthBuffer = -1;
}
IntBuffer intBuffer = BufferUtils.newIntBuffer(16); // See http://lwjgl.org/forum/index.php?topic=1314.0;wap2
intBuffer.clear();
Gdx.gl.glGenFramebuffers(1, intBuffer);
frameBuffer = intBuffer.get(0);
intBuffer.clear();
Gdx.gl.glGenTextures(1, intBuffer);
colorTexture = intBuffer.get(0);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, colorTexture);
Gdx.gl.glTexImage2D(GL20.GL_TEXTURE_2D, 0, GL20.GL_RGBA, width, height
, 0, GL20.GL_RGBA, GL20.GL_UNSIGNED_BYTE, null);
Gdx.gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MIN_FILTER, GL20.GL_NEAREST);
Gdx.gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MAG_FILTER, GL20.GL_NEAREST);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, 0);
intBuffer.clear();
Gdx.gl.glGenTextures(1, intBuffer);
depthTexture = intBuffer.get(0);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, depthTexture);
Gdx.gl.glTexImage2D(GL20.GL_TEXTURE_2D, 0, GL20.GL_DEPTH_COMPONENT, width, height
, 0, GL20.GL_DEPTH_COMPONENT, GL20.GL_UNSIGNED_SHORT, null);
Gdx.gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MIN_FILTER, GL20.GL_NEAREST);
Gdx.gl.glTexParameteri(GL20.GL_TEXTURE_2D, GL20.GL_TEXTURE_MAG_FILTER, GL20.GL_NEAREST);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, 0);
Gdx.gl.glBindFramebuffer(GL20.GL_FRAMEBUFFER, frameBuffer);
Gdx.gl.glFramebufferTexture2D(GL20.GL_FRAMEBUFFER, GL20.GL_COLOR_ATTACHMENT0
, GL20.GL_TEXTURE_2D, colorTexture, 0);
Gdx.gl.glFramebufferTexture2D(GL20.GL_FRAMEBUFFER, GL20.GL_DEPTH_ATTACHMENT
, GL20.GL_TEXTURE_2D, depthTexture, 0);
int status = Gdx.gl.glCheckFramebufferStatus(GL20.GL_FRAMEBUFFER);
if (status != GL20.GL_FRAMEBUFFER_COMPLETE)
{
System.out.println("frame buffer not complete. status " + Integer.toHexString(status));
System.exit(0);
}
Gdx.gl.glBindFramebuffer(GL20.GL_FRAMEBUFFER, 0);
status = Gdx.gl.glCheckFramebufferStatus(GL20.GL_FRAMEBUFFER);
if (status != GL20.GL_FRAMEBUFFER_COMPLETE)
{
System.out.println("default buffer not complete. status " + Integer.toHexString(status));
System.exit(0);
}
I am not sure at all if i have made mistakes in setting up the render buffer or either the color texture or depth texture attachments. Anyway, on to the rendering loop
// update cameras and things
// setup rendering to off screen framebuffer
Gdx.gl.glBindFramebuffer(GL20.GL_FRAMEBUFFER, frameBuffer);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
// draw things
// setup rendering to default framebuffer
Gdx.gl.glBindFramebuffer(GL20.GL_FRAMEBUFFER, 0);
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
shader.begin();
// setup shader stuff
Gdx.gl.glActiveTexture(0);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, depthTexture);
shader.setUniformi("u_fbDepth", 0);
Gdx.gl.glActiveTexture(1);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, colorTexture);
shader.setUniformi("u_fbColor", 1);
// draw things with shader
shader.end();
Again i am not sure i am setting things up the right way. The idea here is hopefully pretty clear. Render to the off screen frame buffer then use the depth and color textures from that frame buffer as textures to sample in the final shader that renders to the default framebuffer.
The depth and color textures that end up in my fragment shader are just empty however. Black screen. I know the fragment shader is not the problem - if i sample a different texture i see the texture as expected. I know that the drawing its self is not the problem - if i render what i would want to render to the off screen frame buffer directly to the default frame buffer i see what i expect.
I got it. There's a bit of a gotcha with setting active textures. The function glActiveTexture expects one of the GL_TEXTURE0 type constants, but the shader uniform just wants to be the integer in the constant name.
basically
Gdx.gl.glActiveTexture(0);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, depthTexture);
shader.setUniformi("u_fbDepth", 0);
Gdx.gl.glActiveTexture(1);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, colorTexture);
shader.setUniformi("u_fbColor", 1);
needed to be
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE0);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, depthTexture);
shader.setUniformi("u_fbDepth", 0);
Gdx.gl.glActiveTexture(GL20.GL_TEXTURE1);
Gdx.gl.glBindTexture(GL20.GL_TEXTURE_2D, colorTexture);
shader.setUniformi("u_fbColor", 1);
The popular game Words with Friends draws letter tiles at the game board as a single entity -
You can see a yellow linear gradient applied to all letter tiles in the following screenshot and also an emboss effect on the edge:
In my word game I would like to have similar effects:
So I create a game board sized mBitmap, then draw all tiles into it and finally draw the bitmap into my custom view -
Setup:
setLayerType(View.LAYER_TYPE_SOFTWARE, null);
// create yellow linear gradient
mGradStart = new Point(3 * mWidth / 4, mHeight / 3);
mGradEnd = new Point(mWidth / 4, 2 * mHeight / 3);
LinearGradient gradient = new LinearGradient(
mGradStart.x,
mGradStart.y,
mGradEnd.x,
mGradEnd.y,
new int[]{ 0xCCFFCC00, 0xCCFFCC99, 0xCCFFCC00 },
null,
TileMode.CLAMP);
// create the big bitmap holding all tiles
mBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mPaintGrad = new Paint();
mPaintGrad.setShader(gradient);
mPaintEmboss = new Paint();
mPaintEmboss.setShader(gradient);
EmbossMaskFilter filter = new EmbossMaskFilter(
new float[] { 0f, 1f, 0.5f }, 0.8f, 3f, 3f);
mPaintEmboss.setMaskFilter(filter);
Drawing:
#Override
protected void onDraw(Canvas canvas) {
mGameBoard.draw(canvas);
// draw all tiles as rectangles into big bitmap
// (this code will move to onTouchEvent later)
mBitmap.eraseColor(Color.TRANSPARENT);
for (SmallTile tile: mTiles) {
mCanvas.drawRect(
tile.left,
tile.top,
tile.left + tile.width,
tile.top + tile.height,
mPaintGrad);
tile.draw(mCanvas);
}
canvas.drawBitmap(mBitmap, 0, 0, mPaintEmboss); // emboss NOT displayed
canvas.drawText("TEXT WORKS OK", 400, 400, mPaintEmboss); // ebmoss OK
canvas.drawRect(300, 600, 800, 1200, mPaintEmboss); // emboss OK
}
The EmbossMaskFilter effect works OK with drawText() and drawRect() calls, but it does NOT work for the drawBitmap():
My question: is it possible to use some combinations of PorterDuff.Mode (and extractAlpha?) to draw an emboss around my big bitmap?
UPDATE:
By looking at HolographicOutlineHelper.java I have been able to add an outer shadow:
with the following code in MyView.java -
Setup:
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
mScale = getResources().getDisplayMetrics().density;
mGradStart = new Point(3 * mWidth / 4, mHeight / 3);
mGradEnd = new Point(mWidth / 4, 2 * mHeight / 3);
LinearGradient gradient = new LinearGradient(
mGradStart.x,
mGradStart.y,
mGradEnd.x,
mGradEnd.y,
new int[]{ 0xCCFFCC00, 0xCCFFCC99, 0xCCFFCC00 },
null,
TileMode.CLAMP);
mBitmap = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mPaintGrad = new Paint(Paint.ANTI_ALIAS_FLAG | Paint.FILTER_BITMAP_FLAG);
mPaintGrad.setShader(gradient);
mPaintBlur = new Paint();
mPaintBlur.setColor(Color.BLACK);
BlurMaskFilter blurFilter = new BlurMaskFilter(mScale * 1, Blur.OUTER);
mPaintBlur.setMaskFilter(blurFilter);
}
Drawing:
private void prepareBitmaps() {
mBitmap.eraseColor(Color.TRANSPARENT);
for (SmallTile tile: mTiles) {
mCanvas.drawRect(
tile.left,
tile.top,
tile.left + tile.width,
tile.top + tile.height,
mPaintGrad);
tile.draw(mCanvas);
}
mAlphaBitmap = mBitmap.extractAlpha(mPaintBlur, mOffset);
}
#Override
protected void onDraw(Canvas canvas) {
mGameBoard.draw(canvas);
canvas.drawBitmap(mAlphaBitmap, mOffset[0], mOffset[1], mPaintBlur);
canvas.drawBitmap(mBitmap, 0, 0, mPaintGrad);
}
but unfortunately the app is acting slow now - and I still don't know how to add an emboss effect around the bitmap.
I'm not sure i got exacly what you need, but if you just want to apply EmbossMaskFilter around some png letter with alpha channel, you can pretty much do this trick with
EmbossMaskFilter filter = new EmbossMaskFilter(new float[]{1, 1, 1}, 0.5f, 0.6f, 2f);
Paint paintEmboss = new Paint();
paintEmboss.setMaskFilter(embossMaskFilter);
Bitmap helperBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas helperCanvas = new Canvas(helperBitmap);
Bitmap alpha = src.extractAlpha();
helperCanvas.drawBitmap(alpha, 0, 0, paintEmboss);
alpha.recycle();
...
canvas.drawBitmap(helperBitmap, 0, 0, anyPaint);
You will never want all of this code in 1 onDraw, because it creates lots of objects in memory. And src.extractAlpha(); creates new Bitmap each time. (Btw i always get out of memory error from your project git . Added mAlphaBitmap.recycle(); and it could at least boot. But it still lagges like hell)
So, i played with your git repository and got some results. Here is demo image and git repo of first commit:
But then i realized, that you don't need EmbossMaskFilter around letters, you need them around rectangles. And it can be done pretty much the same way. Here is how i done this:
Create new helper static Bitmap and Canvas for emboss background, just like mAlphaBitmap
On each prepareBitmaps() paint rects on helper bitmap. Solid color with no alpha.
Extract alpha from created bitmap like this Bitmap alpha = helperCanvas.extractAlpha();
Draw extracted alpha bitmap on helper with paint with emboss filter helperCanvas.drawBitmap(alpha, 0, 0, paintEmboss);
In onDraw print helperBitmap with some alpha before main Bitmap.
Here is screenshot without alpha(because it is much easier to see the shapes this way)
Here is git demo of this version: https://github.com/varren/AndroidEmbossMaskFilterForPng/blob/1d692d576e78bd434252a8a6c6ad2ee9f4c6dbd8/app/src/main/java/de/afarber/mytiles2/MyView.java
And here is essential part of code i changed in your project:
private static final EmbossMaskFilter filter =
new EmbossMaskFilter(new float[]{1, 1, 1}, 0.5f, 0.6f, 2f);
private static Canvas helperCanvas;
private static Paint paintEmboss;
public Canvas getHelperCanvas(int width, int height){
if (mAlphaBitmap == null) {
mAlphaBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
helperCanvas = new Canvas(mAlphaBitmap);
paintEmboss = new Paint();
paintEmboss.setColor(Color.BLACK);
}
return helperCanvas;
}
private void prepareBitmaps() {
mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
helperCanvas = getHelperCanvas(mBitmap.getWidth(),mBitmap.getHeight());
helperCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
paintEmboss.setMaskFilter(null);
paintEmboss.setAlpha(255);
for (SmallTile tile: mTiles) {
if (!tile.visible) continue;
helperCanvas.drawRect(tile.left,tile.top,tile.left + tile.width,
tile.top + tile.height,paintEmboss);
mCanvas.drawRect(tile.left, tile.top,tile.left + tile.width,
tile.top + tile.height, mPaintGrad);
tile.draw(mCanvas);
}
paintEmboss.setMaskFilter(filter);
Bitmap alpha = mAlphaBitmap.extractAlpha();
helperCanvas.drawBitmap(alpha, 0, 0, paintEmboss);
}
protected void onDraw(Canvas canvas) {
// ...
paintEmboss.setAlpha(255); //todo change alpha here
if(mAlphaBitmap!= null)canvas.drawBitmap(mAlphaBitmap, 0,0, paintEmboss);
if(mBitmap!= null)canvas.drawBitmap(mBitmap, 0, 0, mPaintGrad);
// ...
}
And the last 3-d step i made is to move everything from onDraw to prepareBitmaps() and preformance is fine now, but we have text destortion on resize. so here is source code for this step.
And here is kinda fine working final solution. Moving all paints with filters solved preformance issues, but i think there are still better options to implement this. As i said erlier i don't know is it what you need, but this code pretty much creates Emboss around Bitmap
PS: kinda cool effect when splitting and adding cells together
PS2: new EmbossMaskFilter(new float[] { 0f, 1f, 0.5f }, 0.8f, 3f, 3f); this will not look the same on diferent devices with diferent screen resolution
Here's a suggestion using a custom layout.
You'll need your own layout for the scrabble board. Since it's grid, this should be pretty easy to code.
The basic idea is to have a set of PNG shadow images, one for each type of combination of adjacent cells. In your layout onDraw(), draw the shadows first, then draw the tile in onLayout().
In onDraw(), iterate through your array of tiles placeholders. If you have a tile, then for each edge, inspect the adjacent cells. Depending on what's adjacent, choose the correct shadow image and draw it.
You can reduce the number of shadow images substantially by having a shadow image which is exactly the width of a tile and then specializing the corner area: one for 270 degrees, one for straight alignment, one for 90 degrees.
I don't know if using porter-duff can help since you still need to determine all these "edge" cases (no pun intended).
I have a medical device that sends pixel's values in order to plot as an image (frame after frame).
I need to take the pixels and build from them an image on the screen. Currently with the code I wrote, I manage to receive 2fps for image size of 800x600.
What is the fastest way plot an image on screen? and doing it continuously.
Bitmap mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
Canvas c = new Canvas(mBitmap);
Paint paint = new Paint();
int[] colorMatrix = new int[width * height];
for (int i = 0; i < imageXY.length; i++) {
int indexValue = Integer.parseInt(strValueIndex[i]);
int pixelValue = Integer.parseInt(imageValue[indexValue - 1]);
int pixelIndex = GetXY(imageXY[i]);
//int pixelIndex = Integer.parseInt(imageXY[i].split(",")[2]);
colorMatrix[pixelIndex] = pixelValue;
}
c.drawBitmap(colorMatrix, 0, width, 0, 0, width, height, false, paint);
myImage.setImageBitmap(mBitmap);
However its take about 500ms for each frame
This is the easiest place to start OpenGL in Android: http://developer.android.com/guide/topics/graphics/opengl.html
I would also look into using multiple cores for this process; although the GPU based calculations may offer higher single core speeds, a fairly "simple" task such as this will be greatly accelerated by utilizing multiple cores and parallel processing, and shouldn't be too hard to implement. Here is an introduction to parallel processing on Android devices.
https://developer.qualcomm.com/blog/multi-threading-android-apps-multi-core-processors-part-1-2
I'm creating a game with libgdx that I want to run at a higher resolution on the desktop, but I want it to scale everything down correctly when I run it on android at smaller resolutions. I've read that the best way to do this is to not use a pixel perfect camera, and instead to use world coordinates, but I'm not sure how to correctly do that.
This is the code I have right now:
#Override
public void create() {
characterTexture = new Texture(Gdx.files.internal("character.png"));
characterTextureRegion = new TextureRegion(characterTexture, 0, 0, 100, 150);
batch = new SpriteBatch();
Gdx.gl10.glClearColor(0.4f, 0.6f, 0.9f, 1);
float aspectRatio = (float)Gdx.graphics.getWidth() / (float)Gdx.graphics.getHeight();
camera= new OrthographicCamera(aspectRatio, 1.0f);
}
#Override
public void render() {
GL10 gl = Gdx.graphics.getGL10();
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
camera.update();
camera.apply(gl);
batch.setProjectionMatrix(camera.combined);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
draw();
}
private void draw() {
//batch.getProjectionMatrix().set(camera.combined);
batch.begin();
batch.draw(characterTextureRegion, 0, 0, // the bottom left corner of the box, unrotated
1f, 1f, // the rotation center relative to the bottom left corner of the box
0.390625f, 0.5859375f, // the width and height of the box
1, 1, // the scale on the x- and y-axis
0); // the rotation angle
batch.end();
}
The texture I'm use is 256x256 with the actual image in it being 100x150.
This is the result I get when I run the game: http://i.imgur.com/HV9Bi.png
The sprite that gets rendered is massive, considering this is the original image: http://i.imgur.com/q1cZT.png
What's the best way to go about making it so that the sprites get rendered at their original size while still keeping the ability to have the game scale correctly when played in different resolutions?
I've only found two solutions, both of which I don't like.
The image showed up how it was supposed to if I used pixel coordinates for the camera, but then that didn't scale at all when I put it on my phone with a different resolution.
I can scale the texture region down when I draw it, but it seems like there is a better way because it is extremely tedious trying to figure out the correct number to scale it by.
Have you ever used the Libgdx setup tool? When you create a project with it, it has a sample image that is displayed. It seems to keep it's ratio correct no matter what size you change the screen to.
public class RotationTest implements ApplicationListener {
private OrthographicCamera camera;
private SpriteBatch batch;
private Texture texture;
private Sprite sprite;
Stage stage;
public boolean leonAiming = true;
#Override
public void create() {
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera(1, h/w);
batch = new SpriteBatch();
texture = new Texture(Gdx.files.internal("data/libgdx.png"));
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
TextureRegion region = new TextureRegion(texture, 0, 0, 512, 275);
sprite = new Sprite(region);
sprite.setSize(0.9f, 0.9f * sprite.getHeight() / sprite.getWidth());
sprite.setOrigin(sprite.getWidth()/2, sprite.getHeight()/2);
sprite.setPosition(-sprite.getWidth()/2, -sprite.getHeight()/2); }....
#Override
public void render() {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.begin();
sprite.draw(batch);
batch.end();
First of all you need to fix boundaries to the world (I mean to your game ). In that world only you actors(game characters) should play. If you are crossing boundaries, manage it with camera like showing up, down, left and right.