Fading CurveVertex() trails using background opacity value not working - java

Using FX2D.
Hi, I'm currently drawing a line at every frame using the curveVertex() function.
Every line stays on the sketch voluntarily by not resetting the background at every step,
which leaves a trail effect.
But I would like to make these trails fade away over time. I tried resetting the background in the draw() function by giving it a small opacity value but it clears all the trails at once every time.
Right now I can only have either all trails or no trails.
//background(0, 0, 0, 10); // Reset background every time
stroke(255, 255, 255, 10); // Draw Line between all nodes
curveVertex(nodes.get(fixId(i)).position.x, nodes.get(fixId(i)).position.y);
with trails

background() does not just set the background color, it clear the entire window. It is not intended to use background within beginShape() / endShape() sequences.
What what to do can be achieved by drawing a rect() with blendMode(DIFFERENCE) on the entire window, at the begin of the frame. e.g.:
void draw() {
// "fade" the entire view
blendMode(DIFFERENCE);
fill(1, 1, 1, 255);
rect(0, 0, width, height);
blendMode(ADD);
// draw shape
// [...]
}
See also the answer to Processing - rendering shapes.

Related

Java draw Image in wrong position, Clip Region position is wrong

When I see my application, it draws my image not on (0,0) but somewhere middle in my program, So I debug my program,and I saw that the clipRegion.lox is 456 and loy is 130 and this is the location that program draw (0,0). So I think that Clip Region position is wrong, but I don't know how to fix it. Any help please?
code:
public void changeState(int bef,int cur){
if(bef==1){
if(cur==2){
intro.setVisible(false);
this.setContentPane(play);
play.init();
play.setVisible(true);
}
}
}
This is when first my Panel is started. In play.init() I set my socket to connect with server program, and start sound file. That is all.
public void paintComponent(Graphics g){
super.paintComponent(g);
this.setBackground(new Color(255,255,255));
g.drawImage(backgroundImg, 0, 0, this);
g.drawImage(player, 368, 280, this);
for(int i=0;i<60;i++){
for(int j=0;j<100;j++){
if(map[i][j]==1){
g.drawImage(stone, (j-10)*32-dx, (i-10)*32, this);
}
else if(map[i][j]==2){
if(i>0&&map[i-1][j]==0) g.drawImage(grass, (j-10)*32-dx, (i-10)*32, this);
else g.drawImage(dirt, (j-10)*32-dx,(i-10)*32,this);
}
}
}
g.drawString(servermessage, 320, 200);
}
I erased my Println code and Thread Sleep Code. It was just for debugging and when I deleted however, nothing changed.
Plus, I repainted it, and it draws in (0,0) but it doesn't draw full screen.
I think that drawn image is the same size as (456,130) to (800,600) so I think the picture is cut out.
I can't post my picture because of low reputation... Any help too?
this.setBackground(new Color(255,255,255));
Don't set the background in the painting method. Set the background in the constructor of your class.
it draws my image not on (0,0) but somewhere middle in my program,
g.drawImage(backgroundImg, 0, 0, this);
No, the image is drawn at (0, 0) which is relative to the location of the panel. This would mean that the panel is not being painted at (0, 0) relative to the frame. This could be because of the layout manager you are using is positioning the panel in the center of the frame. Check your layout code.
I saw that the clipRegion.lox is 456 and loy is 130 and
If you think the clipping area is wrong it may be because your panel does not have a preferred size. Whenever you do custom painting you should override the getPreferredSize() method to return the size of the panel so the layout manager can do their job properly. Maybe the preferred size should be the size of your image?
Read the section from the Swing tutorial on Custom Painting for more information and working examples.

One texture render many times

I have a small texture to tile the background of my game. So I want to draw the texture one by one. What shoud I do with libgdx opengl es.
You can set you texture to repeat simply by:
Texture tilingTexture;
tilingTexture = new Texture("tiling_texture.png");
tilingTexture.setWrap(TextureWrap.Repeat, TextureWrap.Repeat);
//And draw it:
batch.draw(tilingTexture,
xCoordWhereImageMustBeDisplayed, yCoordWhereImageMustBeDisplayed,
xCoordOnImageItself, yCoordOnImageItself,
widthOfImageToDisplay, heightOfImageToDisplay);
So basically if you want to scroll it infinitely you just have to increment the coords of the image itself.
xIncrement += 10;
batch.begin();
batch.draw(tilingTexture, 0, 0, xIncrement,0, Gdx.graphics.getWidh, Gdx.graphics.getHeight);
batch.end();
If xIncrement is larger then the total width of the image it just wraps around. Of course you can do this yourself to reset xIncrement to 0 if it surpasses the image width. But with this wrapping method, if the hightOfImageToDisplay is larger then the image it will just tile next to each other.

Box2dlights - Layering lights

How do you make the box2dlights ignore textures and sprites in ambient lighting? For example I have a stage that has the ambient lighting set to dark. I want my lights to brighten up a platform directly underneath the light, but the background image behind the light should remain dark and not lit up. Currently the lights are the top rendered layer and everything underneath the light is lit up.
The right way to achieve this is the following:
Update your physics and cameras.
Render the light map so you can later fetch the texture from the RayHandler's FrameBuffer.
Render your top layers to a transparent FrameBuffer object, in the desired order, but don't render the light map inside of it. Do not render here your HUD or whatever top-most layers you don't want to be affected by you lighting.
Finish rendering to your FBO and begin rendering to your screen.
Render the background which is not affected by lights.
Bind to Texture Units 0 and 1 the light map and your top layers' FBO Texture.
Begin a Shader you will use to blend your light map with your FBO Texture. The mixing is quite simple (occurs in the Fragment Shader): glFragColor = tex0.rgb * tex1.rgb, and keep tex1.a untouched (tex0 = light map texture, tex1 = fbo texture). The RayHandler's ambient light is lost with this rendering method, so you can pass the ambient light colour to the shader and add it to the light map channels.
Bind the texture units to the shader and perform the rendering. This rendering must be done with alpha blending enabled (SRC_ALPHA, ONE_MINUS_SRC_ALPHA).
Bind again the default Texture Unit so remaining rendering is properly done (TEXTURE_0): render any remaining top-most layers and the HUD, if any.
Some example code:
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
tweenManager.update(delta);
worldUpdate(delta);
/* We have three cameras (foreground + double parallax background) */
moveForegroundCamera(player.getPosition().x, player.getPosition().y);
moveBackground0Camera(player.getPosition().x, player.getPosition().y);
moveBackground1Camera(player.getPosition().x, player.getPosition().y);
cameraMatrixCopy.set(foregroundCamera.combined);
rayHandler.setCombinedMatrix(cameraMatrixCopy.scale(Globals.BOX_TO_WORLD, Globals.BOX_TO_WORLD, 1.0f), foregroundCamera.position.x,
foregroundCamera.position.y, foregroundCamera.viewportWidth * camera.zoom * Globals.BOX_TO_WORLD,
foregroundCamera.viewportHeight * foregroundCamera.zoom * Globals.BOX_TO_WORLD);
rayHandler.update();
rayHandler.render();
lightMap = rayHandler.getLightMapTexture();
fbo.begin();
{
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
/* Draw the second background (affected by lights), the player, the enemies and all the objects */
batch.enableBlending();
batch.setProjectionMatrix(background1Camera.combined);
batch.begin();
background1.draw(batch);
batch.end();
batch.setProjectionMatrix(foregroundCamera.combined);
batch.begin();
// Draw stuff...
batch.end();
}
fbo.end();
/* Now let's pile things up: draw the bottom-most layer */
batch.setProjectionMatrix(background0Camera.combined);
batch.disableBlending();
batch.begin();
background0.draw(batch);
batch.end();
/* Blend the frame buffer's texture with the light map in a fancy way */
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE0);
fboRegion.getTexture().bind(); // fboRegion = new TextureRegion(fbo.getColorBufferTexture());
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE1);
lightMap.bind();
Gdx.gl20.glEnable(Gdx.gl20.GL_BLEND);
Gdx.gl20.glBlendFunc(Gdx.gl20.GL_SRC_ALPHA, Gdx.gl20.GL_ONE_MINUS_SRC_ALPHA);
lightShader.begin();
lightShader.setUniformf("ambient_color", level.getAmbientLightColor());
lightShader.setUniformi("u_texture0", 0);
lightShader.setUniformi("u_texture1", 1);
fullScreenQuad.render(lightShader, GL20.GL_TRIANGLE_FAN, 0, 4);
lightShader.end();
Gdx.gl20.glDisable(Gdx.gl20.GL_BLEND);
Gdx.gl20.glActiveTexture(GL20.GL_TEXTURE0); // Bind again the default texture unit
/* Draw any top-most layers you might have */
hud.draw();
}

Graphics2D is incapable of alpha?

I am implementing layers in a 2D engine of mine and I would like layers to be stackable, and I would also like a feature to 'cut holes' in layers - this means using alpha. However when writing it standalone I can't seem to get anything to use true alpha, it tried to fake it by blending colours together, for instance (my code):
BufferedImage background, foreground;
public GraphicsTest() {
background = new BufferedImage(500,500,BufferedImage.TYPE_INT_ARGB);
foreground = new BufferedImage(500,500,BufferedImage.TYPE_INT_ARGB); // Fully capable of alpha.
Random r = new Random();
int white = Color.white.getRGB();
// Draw random white dots
for (int i=0; i<500; i++) {
int
x = r.nextInt(500),
y = r.nextInt(500);
background.setRGB(x, y, white);
}
}
#Override
protected void paintComponent(Graphics g) {
BufferedImage output = new BufferedImage(500,500,BufferedImage.TYPE_INT_ARGB); // Fully capable of alpha.
Graphics2D canvas = output.createGraphics();
Graphics2D overlay = foreground.createGraphics();
canvas.drawImage(background, 0, 0, null);
overlay.setColor(Color.white);
overlay.fillRect(0, 0, 500, 500);
// Start drawing with alpha
overlay.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1f));
overlay.setColor(new Color(0xFF000000)); // Overwrite/draw full alpha, colour doesn't matter when alpha is 100%
overlay.fillRect(100, 100, 125, 87);
//canvas.setColor(Color.red);
//canvas.fillRect(0, 0, 500, 500);
canvas.drawImage(foreground, 0, 0, null);
overlay.dispose();
canvas.dispose();
g.drawImage(output, 0, 0, null);
// Also write to a file for manual raw pixel checking
try {
// Does output a 32-bit depth image
ImageIO.write(output, "PNG", new File("c:/output.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
This is the most basic test I could think of, I have two images, one for the background and one for the foreground, I am needing to see the background through the foreground in the 127x87 (random sized) box.
Currently it results in a white screen with a black box, the back box should be that part of the background.
I have tried all sorts of methods here, settings the composite and drawing black with full alpha but when combined I never see the background, the setColor(0xFF000000) doesn't seem to be doing anything but drawing black and the composite is the culprit of this 'faking', instead of overwriting FF000000 (black) on a 00FFFFFF (white with no alpha) background yielding FF000000 (what I set it to) it is instead 007F7F7F (grey with no alpha).
The only reason I can see for this is the fact that everything is going through a Graphics2D object, I cannot use output.setRGB as it is slow and I wouldn't know how to draw custom shapes with it.
You need to change 3 things for your code to behave properly.
As #vandale said, you need to use a color with actual alpha with the boolean constructor.
Second, the alpha is the opacity (so it should be 0 for transparent color). You get:
overlay.setColor(new Color(0x0000000, true));
Third, you need to say that your paint operation will actually override whatever was already there (you don't want to draw on top (ATOP) of the existing but rather replace with the transparent color (IN) what was there). You get:
overlay.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, 1f));

Drawing 3D text in Processing

I'm working on a 3D scene in Java using the Processing API. It's a force-directed graph layout algorithm (although that isn't too important). I've got all the graph drawing done -- the nodes, edges, layout, etc. are looking good. Each node on the graph has a label, though, and I'd like to be able to display said label as text next to the node. I've tried working with the text() function, but so far it seems like my code just doesn't work. I see no text anywhere in the scene.
My code looks like the following:
pushMatrix();
translate(width/2, height/2, 0); // put 0,0,0 at the center of the screen
text("foo!", 20, 20, 20);
popMatrix();
And I don't see anything. Just the graph. So what am I missing?
Everything is fine with the tiny bit of code you displayed. You can see a modified version running here:
void setup() {
size(400,400,P3D);
textSize(20);
}
void draw() {
background(0);
translate(width * .5, height*.5,0);
rotateY(map(mouseX,0,width,-PI,PI));
rotateX(map(mouseY,0,height,-PI,PI));
pushMatrix();
text("foo!", -20, 0, 20);
popMatrix();
}
There might be something else along the way. Care to share more information ?
The fill color controls the text color, and defaults to white. So if you are painting white text on a white background, it won't show up. Add fill(0); before you draw text.
Also remember that shapes drawn after you send your text to the screen may over-write your text. The last 'hidden' statement in draw is to paint the screen.
Here's an example of drawing a series of vertical lines (in 2D) with a row of labels at the top:
int startX;
void setup() {
size(400,400);
textSize(12);
startX = width/10;
}
void draw() {
background(255);
int curX = startX;
fill(0); // Set the text color
while (curX < width)
{
line(curX, 30, curX, height-10);
text(curX, curX-(curX/20), 20);
curX += width/10;
}
} // end draw

Categories