I want to render a particle effect in 3D using the Z coordinate. I've tried to implement a own ParticleEffect using Decals instead of Sprites without success.
Is there any other way to render a ParticleEffect using the Z coordinate? Maybe by manipulating the transformation Matrix of the SpriteBatch?
Update:
working code
// update projection each frame since my camera is moving
spriteBatch.setProjectionMatrix(camera3d.projection);
for (ParticleEffect effect : effects){
spriteBatch.setTransformMatrix(camera3d.view);
spriteBatch.getTransformMatrix().translate(x,y,z); // different for each effect
spriteBatch.getTransformMatrix().scale(0.1f,0.1f,0.1f); //optional
spriteBatch.begin();
effect.draw(spriteBatch, delta);
spriteBatch.end();
spriteBatch.getTransformMatrix().idt();
}
If your 3D effect is a parallax effect, meaning your particles face the camera perpendicularily, you can indeed set the transformation matrix of the SpriteBatch
batch.getTransformMatrix().idt().translate(0, 0, z);
batch.begin();
... do your rendering here
batch.end();
// reset the matrix, so you can use the batch for other stuff
batch.idt();
For a perspective effect you'll also have to use perspective projection. The easiest way to cope with this requirement is to use a PerspectiveCamera instead of an OrthographicCamera.
Related
I'm writing a 2d game engine using libgdx where multiple layers of sprites have to be rendered using SpriteBatch with an OrthgraphicCamera. My layers are sorted with a z component : higher z layers should be rendered on top of layers with a lower z.
Currently, I have to render layers sorted by their z component to achieve that. Is there a way, using opengl Z-buffer, to have them rendered out of order, and still show up correctly ?
Fixed by switching to DecalBatch instead of SpriteBatch. Here are the GL commands I use before drawing with the DecalBatch to enable depth-testing :
Gdx.gl.apply {
glClearColor(0f, 0f, 0f, 0f);
glEnable(GL20.GL_DEPTH_TEST)
glClear(GL20.GL_COLOR_BUFFER_BIT or GL20.GL_DEPTH_BUFFER_BIT)
glClearDepthf(1f)
glDepthFunc(GL20.GL_LESS)
}
I am trying to render some sprites and I need the line batch.setProjectionMatrix(cam.combined); in order for the sprites to move independently from the camera, however when I add this line the sprites suddenly turn abnormally large, but without it they are just normal. I have the suspicion that it changes the world dimensions or something like that, because the the boundaries I set for the player sprite are also expanded, just like the size of the sprites, but the background (a tiledmap rendered with a OrthogonalTiledMapRenderer) stays the same.
This is the normal rendering as it should be: https://ibb.co/m4T2GT
This is the rendering i get when using setProjectionMatrix: https://ibb.co/j0EL38
(I used an external site for the pictures because for some reason I could not add them here)
This is my render function.
player.draw(..);
and
e.draw(..);
just call the draw function of the Sprite class.
public void render() {
handleInput();
renderer.setView(cam);
renderer.render();
batch.setProjectionMatrix(cam.combined);
batch.begin();
player.draw(batch);
for (Entity e: enemies) e.draw(batch);
batch.end();
}
You can use the float: cam.zoom to change how large everything appears. Change it in setup or just after you initialise the camera object, then it should remain at that zoom.
If that doesn't work, you might need to set the map rendering to the camera's projection matrix as well.
It's my first time attempting to create a basic light system that uses a black texture with a white circle on top. I read various threads about the issue but I just don't know what I am doing wrong.
What I want is the ambient to be dark and the light to be well white but changing the spritebatch color to something darker will cause the light to be darker to EVEN if I reset the color when drawing the light texture
So this is what I want (did this by forcing the light texture draw 5 times but that isn't a solution, it's an hack):
This is what I get (only 1 light texture is drawn but isn't very visible):
This is what I get without darkening the spritebatch:
Main code:
Game.sb.begin();
//Make stuff darker
Game.sb.setColor(0.1f, 0.1f, 0.1f,1f);
sb.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
lvl.render();
//Reset color
Game.sb.setColor(1f, 1f, 1f,1f);
sb.setBlendFunction(GL20.GL_DST_COLOR, GL20.GL_SRC_ALPHA);
//This draws all lights by drawing a texture with the above blending function
lightM.render();
Game.sb.end();
Light object draw method:
Game.sb.setColor(c.r,c.b,c.g, 1f);
Utils.drawTexture(Assets.get("sprites/lightcircle2.png", Texture.class), pos, size, true);
Game.sb.setColor(1,1,1,1);
Am I making some kind of error with the setcolor? I been considering using a FrameBuffer but I am not sure if it will give me the light effect I want
By the way this is my light texture (it's CC0):
You can achieve your requirement by these ways :
By using Shaders. Here is a small video and article on that video.
By use FBO and Blending, Here is one of my answer on this topic.
You can use box2dlight, even without using box2dbody(if you don't want any shadows)
World world = new World(new Vector2(0,0),false);
RayHandler rayHandler = new RayHandler(world);
rayHandler.setCombinedMatrix(stage.getCamera().combined); //<-- pass your camera combined matrix
new PointLight(rayHandler,1000, Color.WHITE,radius,x_position,y_position);
And at last call rayHandler.updateAndRender(); after all your rendering in your render() method.
Recently I switched from using an array of integers as my screen in Java to using a library. The library I'm using is LibGDX, and the conversion for me is quite different. Most things I have already started to get the hang of, and I'm still writing a bit of the code myself.
At this point, I'm curious if I can limit the rendering range of Sprites and any other factor of drawing, such as if a sprite stuck half-way out of a box, it wouldn't render the part that was sticking out (as so:)
Is there a way to render in a specific range, and if it is partially out of the range, it doesn't render what is out of the range, or will I have to do that myself?
You can do simple "clipping" to a rectangle with the LibGDX ScissorStack.
Because OpenGL is stateful and many of the LibGDX drawing APIs cache, be sure to "flush" or "end" your batches within the range of the scissors. See libgdx ScissorStack not working as expected and libgdx Cutting an image
If i did not missunderstand you, you are looking for camera.
The camera lets you define a Viewport (size) and you only see things inside this Viewport.
You can also move it arroung to see other parts of the world.
For example:
OrthographicCamera cam = new OrthographicCamera(80, 45);
This defines a camera, which showes you 80 units in x and 45 units in y. It P(0/0) by default is in the middle of the screen, so this camera shows objects from -40 to +40 in x and -22.5 to + 22.5 in y.
You can move it, so that the P(0/0) is in the left lower corner:
camera.position.x = -40;
camera.position.y = -22.5;
camera.update();
This should move the camera to the left by 40 units and down by 22.5 units, so that the P(0/0) is the left lower corner. Don't forget to call update() as this recalculates the projection and view matrix.
Finally, to draw with this camera, you need to set the SptieBatchs projectionMatrix to the one of the camera:
spriteBatch.setProjectionMatrix(camera.combined);
Now you can use this SpriteBatch to draw.
You should also consider to se ViewFrustum-Culling, which means, that you don't draw things out of the camera, because they will never appear on screen, but the draw call costs some performance.
I'm having issues with the Camera class in libGDX, I just can't visually move it even though its position changes.
This is how I setup the camera:
camera = new OrthographicCamera(frustumWidth, frustumHeight);
This is how I change its position:
world.onUpdate(deltaTime, camera);
renderer.render(world);
camera.position.set(MathUtils.random(0, 800), MathUtils.random(0, 480), 0);
//camera.position.set(
// world.dynamicObjects.get(GameWorld.MainPgID).pos.x * GameWorld.frustumToWorldRatio,
//world.dynamicObjects.get(GameWorld.MainPgID).pos.y * GameWorld.frustumToWorldRatio, 0);
I submit the changes at the beginning of the .render function:
camera.update();
batcher.setProjectionMatrix(camera.combined);
batcher.begin();
polygonBatcher.begin();
As I've said the position does change, and yet of the many combinations I've tried none works.
Perhaps I misunderstood how the Camera works and I need to move the objects and not the camera? Seems to be stupid to me, after all it's called camera for a reason.
You have to apply the combined projection matrix on every batch/renderer you want it to affect.
But besides of that it seems to be fine. Try to debug it step by step.
Setup a simple project with only new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight()); and some lines (ShapeRenderer) or sprites (SpriteBatch), set the projection matrix to camera.combined, change camera.position and update() the camera. That should do it.
Then when you change camera.position all the renderer with the camera's frustum should offset accordingly without changing the offsets of the sprites/geometry.
btw. the viewport is not 0 - 800, but rather -400 - 400 for x and respectively for y;