So drawing a shape should be really easy, right? Well, the following draws exactly nothing.
...why?
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
shapeRenderer.setProjectionMatrix(camera.combined);
shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
shapeRenderer.setColor(Color.WHITE);
shapeRenderer.rect(WIDTH / 2, HEIGHT / 2, 50, 50);
shapeRenderer.end();
Make sure your camera is properly initialized.
For Example:
camera = new OrthographicCamera(); //Put this in init
camera.setToOrtho(0,0,WIDTH,HEIGHT);
Related
Is there a way in LibGDX to create a polygon shaped mask? I know how to do a mask with squares and circles but not a polygon. The below code works and renders a mask correctly using a rectangle.
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Gdx.gl.glClearDepthf(1f);
Gdx.gl.glClear(GL20.GL_DEPTH_BUFFER_BIT);
Gdx.gl.glDepthFunc(GL20.GL_LESS);
Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
Gdx.gl.glDepthMask(true);
Gdx.gl.glColorMask(false, false, false, false);
// Renders the rectangle
shapes.begin(ShapeRenderer.ShapeType.Filled);
shapes.setColor(1, 1, 1, 1);
shapes.rect(Gdx.graphics.getWidth() / 2, gdx.graphics.getHeight() / 2, 200f, 200);
shapes.end();
batch.begin();
Gdx.gl.glColorMask(true, true, true, true);
Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
Gdx.gl.glDepthFunc(GL20.GL_EQUAL);
bg.draw(batch);
batch.end();
Gdx.gl.glDisable(GL20.GL_DEPTH_TEST);
This code below however does not work and simply renders a black screen.
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
Gdx.gl.glClearDepthf(1f);
Gdx.gl.glClear(GL20.GL_DEPTH_BUFFER_BIT);
Gdx.gl.glDepthFunc(GL20.GL_LESS);
Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
Gdx.gl.glDepthMask(true);
Gdx.gl.glColorMask(false, false, false, false);
// This should be the polygon being rendered as a mask here
polyBatch.begin();
polygonSprite.draw(polyBatch);
polyBatch.end();
batch.begin();
Gdx.gl.glColorMask(true, true, true, true);
Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
Gdx.gl.glDepthFunc(GL20.GL_EQUAL);
bg.draw(batch);
batch.end();
Gdx.gl.glDisable(GL20.GL_DEPTH_TEST);
This code below however renders the polygon just fine and uses the same coordinates as the last example.
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
// This polygon uses the same coordinates as the last example
// however it now displays the polygon.
polyBatch.begin();
polygonSprite.draw(polyBatch);
polyBatch.end();
Try moving the batch.begin(); in the third paragraph downwards so that it doesn't enclose the Gdx.gl functions, like that:
//batch.begin();
//from here
Gdx.gl.glColorMask(true, true, true, true);
Gdx.gl.glEnable(GL20.GL_DEPTH_TEST);
Gdx.gl.glDepthFunc(GL20.GL_EQUAL);
//to here
batch.begin();
bg.draw(batch);
batch.end();
Gdx.gl.glDisable(GL20.GL_DEPTH_TEST);
I use ortho camera and FitViewport at my project.
In my render() method i create a fremeBuffer to store actual state of my game, then create a pixmap of that buffer and finally i set a new shader and do my postprocess stuff with that frame:
//--- render frame to buffer
screenBuffer.begin();
camera.update();
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(img, 0, 0);
batch.end();
stage.draw();
//--- create pixmap from that buffer
pixmap = ScreenUtils.getFrameBufferPixmap(0, 0,screenBuffer.getWidth(), screenBuffer.getHeight());
batch.flush();
screenBuffer.end();
//--- create texture from pixmap
renderedScreenTexture = new Texture(pixmap);
//--- finally render frame with postprocess shader
camera.update();
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setShader(monoShader);
batch.setProjectionMatrix(camera.combined);
batch.begin();
batch.draw(renderedScreenTexture, 0,0);
batch.draw(renderedScreenTexture, 0, 0, 640, 320, 0, 0, 640, 320, false, true);
batch.end();
At my resize method I have:
viewport.update(width, height);
camera.position.set(camera.viewportWidth / 2,camera.viewportHeight / 2, 0);
The problem is that after resizing a window FitViewport doesen't work.
When i remove a creating frameBuffer from render method FitViewport works fine.
Can anybody tell me what is wrong with my code or whole concept?
Try this:
// the viewPort you are using
FitViewport v = viewport;
// end your buffer with your viewPort's position and size
screenBuffer.end(v.getScreenX(),v.getScreenY(),
v.getScreenWidth(),v.getScreenHeight());
You may have to call fitViewport.apply() before drawing your frameBuffer.
I'm working on 3d app in libgdx engine.
I just figured out that decalBatch isn't drawing into stencil buffer.
I wanned to make stencil masks for 3d world, and it's not working at all.
This is the code which works for sprite batch, but it's not working with decal batch.
Pls help!
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_STENCIL_BUFFER_BIT);
// batch.setProjectionMatrix(camera.combined);
// setup drawing to stencil buffer
Gdx.gl20.glEnable(GL20.GL_STENCIL_TEST);
Gdx.gl20.glStencilFunc(GL20.GL_ALWAYS, 0x1, 0xffffffff);
Gdx.gl20.glStencilOp(GL20.GL_REPLACE, GL20.GL_REPLACE, GL20.GL_REPLACE);
Gdx.gl20.glColorMask(false, false, false, false);
// draw base pattern
shapeRenderer.begin(ShapeType.Filled);
shapeRenderer.identity();
shapeRenderer.setColor(1f, 0f, 0f, 0.5f);
shapeRenderer.rect(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), 100, 100);
shapeRenderer.end();
spriteBatch.begin();
// fix stencil buffer, enable color buffer
Gdx.gl20.glColorMask(true, true, true, true);
Gdx.gl20.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_KEEP);
// draw where pattern has NOT been drawn
Gdx.gl20.glStencilFunc(GL20.GL_NOTEQUAL, 0x1, 0xff);
// decalBatch.add(decal);
// decalBatch.flush();
spriteBatch.draw(Assets.instance.background, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
// draw where pattern HAS been drawn.
// Gdx.gl20.glStencilFunc(GL20.GL_EQUAL, 0x1, 0xff);
// spriteBatch.draw(Assets.instance.actor1, -Gdx.graphics.getWidth() /
// 2, -Gdx.graphics.getHeight() / 2, Gdx.graphics.getWidth(),
// Gdx.graphics.getHeight());
spriteBatch.end();
EDIT:
I figured out that there should be clearing of Depth buffer, and enabling and disabling of DepthMask, but I cant manage it to work.
Oh I just figured it out.
Depth buffer must be enabled couse Decals are in 3d world.
this is the solution if somebody is interested:
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_STENCIL_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
// setup drawing to stencil buffer
Gdx.gl20.glEnable(GL20.GL_STENCIL_TEST);
Gdx.gl20.glStencilFunc(GL20.GL_ALWAYS, 0x1, 0xffffffff);
Gdx.gl20.glStencilOp(GL20.GL_REPLACE, GL20.GL_REPLACE, GL20.GL_REPLACE);
Gdx.gl20.glColorMask(false, false, false, false);
Gdx.gl20.glDepthMask(false);
// draw base pattern
shapeRenderer.begin(ShapeType.Filled);
shapeRenderer.identity();
shapeRenderer.setColor(1f, 0f, 0f, 0.5f);
shapeRenderer.rect(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2, 100, 100);
shapeRenderer.end();
// fix stencil buffer, enable color buffer
Gdx.gl20.glColorMask(true, true, true, true);
Gdx.gl20.glDepthMask(true);
Gdx.gl20.glStencilOp(GL20.GL_KEEP, GL20.GL_KEEP, GL20.GL_KEEP);
// draw where pattern has NOT been drawn
Gdx.gl20.glStencilFunc(GL20.GL_NOTEQUAL, 0x1, 0xff);
decalBatch.add(decal);
decalBatch.flush();
Gdx.gl20.glDisable(GL20.GL_STENCIL_TEST);
I'm trying to draw on a virtual canvas of proportions 1x1 so that I don't have to constantly multiply out the actual dimensions.
This works perfectly when I draw circles, but it would appear as though it does not work well with rectangles, and I'm not sure why.
When I have the following code:
var canvas = this.canvas;
var ctx = canvas.getContext("2d");
ctx.scale(this.canvas.width, this.canvas.height);
ctx.beginPath();
ctx.arc(.5, .5, .1, 0, 2*Math.PI);
ctx.fillStyle = "red";
ctx.fill();
It works fine, and the circle scales with the canvas.
However, when I merely change it to the following:
var canvas = this.canvas;
var ctx = canvas.getContext("2d");
ctx.scale(this.canvas.width, this.canvas.height);
ctx.fillStyle = "blue";
ctx.fillRect(0,0, .0001, .001);
ctx.beginPath();
ctx.arc(.5, .5, .1, 0, 2*Math.PI);
ctx.fillStyle = "red";
ctx.fill();
the rectangle takes up the entirety of the screen and even covers up the circle, even though the circle is drawn after the rectangle. It should, obviously, be taking up a very minute amount of space on the canvas.
It might be worth noting that this occurs in a game loop.
However, the following works as expected, with a red circle appearing above a blue backdrop
var canvas = this.canvas;
var ctx = canvas.getContext("2d");
ctx.fillStyle = "blue";
ctx.fillRect(0,0, 50, 50);
ctx.beginPath();
ctx.arc(10, 10, 20, 0, 2*Math.PI);
ctx.fillStyle = "red";
ctx.fill();
If you're calling this repeatedly in a game loop, the scale method will increase the scale of your transform, every time through the loop. So you end up with everything growing. Since you're not showing your actual code, it's hard to tell why the circle isn't affected.
Try calling scale() only once, or use save() and restore(), or just reset the transform at the start of the loop, before calling scale():
ctx.setTransform(1, 0, 0, 1, 0, 0);
I develope a 2D game and use OrthographicCamera and Viewport to resize virtaul board to real display size. I add images to stage and use ClickListener to detect clicks. It works fine, but when I change resolution it works incorrent(can't detect correct actor, I think the problem with new and original x and y). Is there any way to fix this?
You will need to translate the screen coordinates to world coordinates.
Your camera can do that. You can do both ways, cam.project(...) and cam.unproject(...)
Or if you are already using Actors, don't initialize a camera yourself, but use a Stage. Create a Stage and add the actors to it. The Stage will then do coordinate translation for you.
Once me too suffered from this problem but at end i got the working solution, for drawing anything using SpriteBatch or Stage in libgdx. Using orthogrphic camera we can do this.
first choose one constant resolution which is best for game. Here i have taken 1280*720(landscape).
class ScreenTest implements Screen{
final float appWidth = 1280, screenWidth = Gdx.graphics.getWidth();
final float appHeight = 720, screenHeight = Gdx.graphics.getHeight();
OrthographicCamera camera;
SpriteBatch batch;
Stage stage;
Texture img1;
Image img2;
public ScreenTest(){
camera = new OrthographicCamera();
camera.setToOrtho(false, appWidth, appHeight);
batch = new SpriteBatch();
batch.setProjectionMatrix(camera.combined);
img1 = new Texture("your_image1.png");
img2 = new Image(new Texture("your_image2.png"));
img2.setPosition(0, 0); // drawing from (0,0)
stage = new Stage(new StretchViewport(appWidth, appHeight, camera));
stage.addActor(img2);
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(img, 0, 0);
batch.end();
stage.act();
stage.act(delta);
stage.draw();
// Also You can get touch input according to your Screen.
if (Gdx.input.isTouched()) {
System.out.println(" X " + Gdx.input.getX() * (appWidth / screenWidth));
System.out.println(" Y " + Gdx.input.getY() * (appHeight / screenHeight));
}
}
//
:
:
//
}
run this code in Any type of resolution it will going to adjust in that resolution without any disturbance.
I just think Stage is easy to use.
If there are some wrong,i consider you should check your code:
public Actor hit(float x, float y)