libGDX how to draw a rectangle in an InputProcessor - java

What is the proper way to use the InputProcessor to draw a shape with the ShapeRenderer because usually I create it in the Render thread but the InputProcessor runs before the Render so it gets erased from the render thread.
For example
render()
{
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
//draw rectangle if mouse clicked
}
(^^^ does work)
vs
(does not work)
render()
{
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
//???
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
//draw rectangle
}

Related

Libgdx TouchListner on gameObjects (Phone Screen)

I have a problem with my TouchListener on a Libgdx game.
On my Gamerenderer I have this:
private OrthographicCamera camera;
private Vector3 input;
private Array<Objects> objects;
private SpriteBatch batch;
//In Constructor
camera = new OrthographicCamera();
camera.setToOrtho(false, Configuration.screenWidth, Configuration.screenHeight);
batch = new SpriteBatch();
batch.setProjectionMatrix(camera.combined);
objects = myGame.Objects();
input = new Vector3(0, 0, 0);
//My Renderer
public void render(float runtime){
Gdx.app.log("GameRenderer: ", "Render()");
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
input.x = Gdx.input.getX();
input.y = Gdx.input.getY();
camera.unproject(input);
batch.begin();
for (Objects object:objects) {
object.getFont().draw(batch,object.getGlyphLayout(),object.getX(),object.getY());
object.getRec().set(object.getX(),object.getY(),object.getGlyphLayout().width,object.getGlyphLayout().height);
if(Gdx.input.isTouched()){
Gdx.app.log("Clicked", "Touched");
if(object.getRec().contains(input.x, input.y)) {
Gdx.app.log("Clicked", "Great");
}
else {
Gdx.app.log("Clicked", "Noooooooooooo");
}
}
}
}
batch.end();
}
When I run my game it's working fine except the touchlistener sometimes work fine but after several secondes from the touch.
the Gdx.app.log("Clicked", "Touched"); is fired with the touch.
but the Gdx.app.log("Clicked", "Great"); OR the Gdx.app.log("Clicked", "Noooooooooooo"); i must perform a long press until the touch is fired.
Thank You
Edit
I added a ShapeRenderer to see what exactely my objects do like that:
shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
for(Objects object:objects) {
shapeRenderer.setColor(255 / 255.0f, 0 / 255.0f, 0 / 255.0f, 1);
shapeRenderer.rect(object.getRec().x, object.getRec().y, object.getRec().width, object.getRec().height);
shapeRenderer.setColor(0 / 255.0f, 0 / 255.0f, 255 / 255.0f, 1);
shapeRenderer.rect(object.getX(), object.getY(), object.getGlyphLayout().width, object.getGlyphLayout().height);
}
shapeRenderer.end();
Then I have this result:
The Black Rectangle is the object and the Blue one is the ShapeRenderer of the object on top of ShapeRenderer of object's Rectangle.
Now when I click on the object it don't fire the click, but when I click on the ShapeRenderer it fire it.
Check this solution :
#Override
public void create() {
// Codes
Gdx.input.setInputProcessor(new InputAdapter () {
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
// Insert your code
return true;
}
}
);
//Codes
}
Putting Gdx.input.isTouched() inside the loop is not a good idea.
Finnaly I solved it, just in case if someone have the same problem it has been located at:
object.getRec().set(object.getX(),object.getY(),object.getGlyphLayout().width,object.getGlyphLayout().height);
I replaced object.getY()
with object.getY()-object.getGlyphLayout().height

LibGDX shader not working for FBO texture

I have a shader and I want to run the shader on the whole rendered image at the end instead of each individual sprite that I render on screen. For this purpose I created an FBO, I render the all my images to the FBO and then I render to colorBufferTexture generated by the FBO. There is just one problem, the shader does not work when I render the FBO texture. The withoutFbo() method render the image with the shader working just fine, but the withFbo() method only renders the image without the shader. Also I know that the shader in withFbo() is working because if I try to render something other then the colorBufferTexture from the FBO the shader will work. So why isn't the shader working with the texture generated by the FBO?
Note: The shader is working with this code, the problem is that it doesn't work when I use the fboTexture. If I call batch.draw(sprite, ...) then the shader will work in both the withFbo() and withoutFbo() methods, but I call batch.draw(fboTexture, ...) then it will simply render the FBO texture without applying the shader.
public class Application3 extends ApplicationAdapter
{
float time;
Sprite sprite;
FrameBuffer fbo;
SpriteBatch batch;
Texture noiseTexture;
TextureRegion fboTexture;
ShaderProgram shaderProgram;
#Override public void create()
{
ShaderProgram.pedantic = false;
batch = new SpriteBatch();
sprite = new Sprite(new Texture("game.png"));
sprite.setSize(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
shaderProgram = new ShaderProgram(Gdx.files.internal(Shader.GLITCH2.getVertex()), Gdx.files.internal(Shader.GLITCH2.getFragment()));
noiseTexture = new Texture(Gdx.files.internal(Shader.GLITCH2.getPath() + "noise.png"));
noiseTexture.bind(0);
fbo = new FrameBuffer(Pixmap.Format.RGBA8888, Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), false);
fboTexture = new TextureRegion(fbo.getColorBufferTexture());
fboTexture.flip(false, true);
}
#Override public void render()
{
//withFbo();
withoutFbo();
}
void withoutFbo()
{
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
time += Gdx.graphics.getDeltaTime();
shaderProgram.setUniformi("u_noise", 0);
shaderProgram.setUniformf("u_time", time);
batch.setShader(shaderProgram);
batch.begin();
batch.draw(sprite, sprite.getX(), sprite.getY(), sprite.getWidth(), sprite.getHeight());
batch.setShader(null);
batch.end();
}
void withFbo()
{
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
time += Gdx.graphics.getDeltaTime();
fbo.begin();
batch.begin();
batch.draw(sprite, sprite.getX(), sprite.getY(), sprite.getWidth(), sprite.getHeight());
batch.end();
fbo.end();
shaderProgram.setUniformi("u_noise", 0);
shaderProgram.setUniformf("u_time", time);
batch.setShader(shaderProgram);
batch.begin();
batch.draw(fboTexture, sprite.getX(), sprite.getY(), sprite.getWidth(), sprite.getHeight());
batch.setShader(null);
batch.end();
}
}

Gdx.input.getY is flipped

I have an issue in LibGDX where when i call upon Gdx.input.getY(), it selects a pixel that's on the other side of the application relative to the center of the screen.
public class Main extends ApplicationAdapter {
private SpriteBatch batch;
private Texture img;
private OrthographicCamera camera;
int xPos;
int yPos;
private Vector3 tp = new Vector3();
BitmapFont font;
#Override
public void create () {
batch = new SpriteBatch();
img = new Texture("crosshair.png");
camera = new OrthographicCamera();
camera.setToOrtho(false, 1280, 720);
font = new BitmapFont();
}
#Override
public void render () {
yPos = Gdx.input.getY();
xPos = Gdx.input.getX();
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.unproject(tp.set(xPos, yPos, 0));
batch.begin();
font.draw(batch,xPos + " , " + yPos, Gdx.input.getX() - 25, Gdx.input.getY() - 5);
batch.draw(img, xPos, yPos);
batch.end();
}
#Override
public void dispose () {
batch.dispose();
img.dispose();
}
Subtracting the viewport height with the touch location won't work, because that would be subtracting world coordinates with touch coordinates. (and even for a pixel perfect projection it would be height - 1 - y). Instead use the unproject method to convert touch coordinates to world coordinates.
There are two problems with your code:
You are never setting the batch projection matrix.
Even though you are using the unproject method, you are never using its result.
So instead use the following:
#Override
public void render () {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.begin();
camera.unproject(tp.set(Gdx.input.getX(), Gdx.input.getY(), 0));
font.draw(batch,tp.x+ " , " + tp.y, tp.x - 25, tp.y - 5);
batch.draw(img, tp.x, tp.y);
batch.end();
}
I would suggest to read the following pages, which describe this and the reasoning behind it in detail:
https://github.com/libgdx/libgdx/wiki/Coordinate-systems
https://xoppa.github.io/blog/pixels/
https://github.com/libgdx/libgdx/wiki/Viewports
It's better to try this
yPos = camera.viewportHeight - Gdx.input.getY();

How can add a drawing function to a button in libgdx?

I am using Screen-2D to build a button. I want give the button a function when it is click a sprite will be drawn how can i do this. This isn't all all my code but enough to show what am talking about.
public void create () {
buttonStyle = new TextButtonStyle();
buttonStyle.up = skin.getDrawable("button");
buttonStyle.over = skin.getDrawable("buttonpressed");
buttonStyle.down = skin.getDrawable("buttonpressed");
buttonStyle.font = font;
button = new TextButton("START", buttonStyle);
stage.addActor(button);
Gdx.input.setInputProcessor(stage);
button.addListener(new InputListener() {
#Override
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
drawTile(200,50);
return true;
}
});
}
// method used to draw a sprite when passing certain coordinates
public void drawTile(int x , int y) {
spriteBatch.draw(sprite, x , y );
}
public void render () {
Gdx.gl.glClearColor(1f, 0f, 0f, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
spriteBatch.begin();
spriteBatch.draw(background, 0, 0);
drawGrid();
spriteBatch.draw(startButton, 0, 0);
stage.draw();
spriteBatch.end()
}
You got the right idea. See this example:
button.addListener(new ChangeListener() {
#Override
public void changed (ChangeEvent event, Actor actor) {
drawTile(200,50);
}
});
https://github.com/libgdx/libgdx/wiki/Scene2d.ui#changeevents
I think you need to read more tutorials about how LibGDX and Scene2D works : Event processing is done before your render method, so any drawing will be erased when you clear screen.
A right approach would be to add a sprite (as Drawable) to a widget group when click firing. Then stage rendering will renderer all your component including your sprites.
Comparaing to MVC pattern : The stage is your model, you modifiy your model when events occurs and the render method is the view of your model (draw your model).

How to draw texture from imputProcessor class? LibGDX

I try drawing stuff using InputProcessor class of LibGDX. But nothing is drawn! Can I draw textures from any other place rather than render () class in LibGDX?
And yes, if I draw in render () class it is drawn ok, but can I draw from somewhere else, like InputProcessor touchDragged?
here is my code
public class mm_imput implements InputProcessor {
SpriteBatch batch=new SpriteBatch();
Texture pixel=new Texture("something.png");
#Override
public boolean touchDragged (int x, int y, int pointer) {
drawSomething();
}
void drawSomething() {
batch.begin();
batch.draw(pixel, 100, 100, 100, 100);
batch.end();
}
}
It should be showing something every time I drag mouse.. How to achieve this?
Your Batch has to be in the Render method of a Screen class.
At this link you'll see what I'm talking about: https://github.com/littletinman/Hype/blob/master/Hype/core/src/com/philiproyer/hype/screens/Details.java
I have a main screen class, with a Render method. I'm implementing the InputProcessor interface.
What I recommend is having the Render method in a condition for when the touch is down.
public void render(float delta) {
Gdx.gl.glClearColor( 0, 0, 0, 1); // Clear the screen with a solid color
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if(isTouching == true) { // check for touching
batch.begin();
batch.draw(pixel, 100, 100, 100, 100);
batch.end();
}
}
Then, in the touchDown method add something like this
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
isTouching = true; // Set boolean to true
return false;
}
To make sure you have it reset when you stop touching do the following in your touchUp method
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
isTouching = false; // Set boolean to false
return false;
}
Let me know if anything isn't quite clear. Best of luck!

Categories

Resources