I have this very simple code:
private static final int SKY_COLOR = Color.rgb(161, 210, 241);
private static final int GROUND_COLOR = Color.rgb(171, 131, 35);
#Override
public void init() {
/* Draw the sky */
SurfaceImage backgroundTopImage = graphics().createSurface(graphics().width(), graphics().height() / 2);
backgroundTopImage.surface().setFillColor(SKY_COLOR);
//--> THE NEXT LINE
backgroundTopImage.surface().fillRect(0, 0, backgroundTopImage.width(), backgroundTopImage.height());
ImageLayer backgroundTop = graphics().createImageLayer(backgroundTopImage);
graphics().rootLayer().addAt(backgroundTop, 0, 0);
/*Draw the ground */
SurfaceImage groundBottomImage = graphics().createSurface(graphics().width(), graphics().height() / 4);
groundBottomImage.surface().setFillColor(GROUND_COLOR);
PlayN.log().debug("groundBottomImage.height()=" + groundBottomImage.height());
groundBottomImage.surface().fillRect(0, 0, groundBottomImage.width(), groundBottomImage.height());
ImageLayer groundBottom = graphics().createImageLayer(groundBottomImage);
PlayN.log().debug("graphics().height() * (3 / 4)=" + graphics().height() * (3f / 4f));
graphics().rootLayer().addAt(groundBottom, 0, graphics().height() * (3f / 4f));
}
The first part is supposed to make a sky on the top half of the screen, and the second part is a background color on the bottom quarter.
I have the following result instead :
And when I comment the first fillRect(), I get the expected result, only for the ground part:
The console shows in both cases:
Updating display mode: 1136 x 640 x 0 #0Hz, fullscreen: false
groundBottomImage.height()=160.0
graphics().height() * (3 / 4)=480.0
Playn 1.8
---- EDIT ----
I reverted to PlayN 1.7, and the same code worked fine.
That's a bug in the 1.8 release, since fixed. I'll make a 1.8.1 release because there are a few pesky bugs that have cropped up.
Related
I am jumping back into an old bunch of code and my Java is very rough. Please be kind.
Problem: I have an application that draws on the canvas. The placement of the screen objects works well. Even Text attached to other objects. However when I place a Text object on the canvas the scale of the canvas halves. I have fiddled off and on for months and can't seem to find the resolution. Any advice would be helpful.
Below is the code to draw the text on screen it is in a class Visualise2D with the other drawing method. All other objects use the same scale etc. This only occurred since I upgraded to Java 15, last java I used was java 8 and it worked fine.
//TEXT
public void paintText(Graphics2D t2D, Color color,Text t, Font font, double bearing, Rectangle2D bounds, double scale, boolean selected, boolean isRotationTool, double enhance) {
//Draws text where ever the user clicks
FontMetrics fm = t2D.getFontMetrics();
t2D.setFont(default_FONT);
AffineTransform at = new AffineTransform();
int x = (int) ((t.getX() - bounds.getX())*(scale));
int y = (int) ((bounds.getHeight() + bounds.getY() - t.getY()) *(scale));
at.setToRotation(Math.toRadians(bearing+270), x,y);
FontRenderContext frc = t2D.getFontRenderContext();
TextLayout layout = new TextLayout(t.getText(), t2D.getFont(), frc);
t2D.setTransform(at);
if (!(selected)) {
t2D.setColor(color);
}
else
{
//pixel size of the circle
float size = 20;//(float) (fm.stringWidth(t.getText())*0.5);
t2D.setColor(p_selectedObjectsColour);
t2D.setStroke(LINE_100);
//Highlight and origin indicator when selected - START
t2D.setColor(p_selectedObjectsColour);
t2D.draw(new Ellipse2D.Double((((t.getX() - bounds.getX())*scale) - size), (((bounds.getHeight() + bounds.getY() - t.getY())*scale) - size), (size*2), (size*2)));
if(isRotationTool){
t2D.drawString(" : \uu27f3 "+dec1P.format(bearing)+"\u00b0",(float) (x + (fm.stringWidth(t.getText())*1.05)),y);
}
t2D.setColor(p_selectedObjectsColour);
t2D.draw(new Rectangle2D.Double(
(t.getX() - bounds.getX())* scale,
((bounds.getHeight() + bounds.getY() - t.getY())*scale)-fm.getStringBounds(t.toString(), t2D).getHeight(),
t.getBounds().getWidth(),
t.getBounds().getHeight()
));
t2D.drawLine((int) (((t.getX() - bounds.getX())) * scale),
(int)(((bounds.getHeight() + bounds.getY())-(t.getY()))*scale),
(int)(((t.getX())- bounds.getX())*scale)+fm.stringWidth(t.getText()),
(int)(((bounds.getHeight() + bounds.getY())-(t.getY()))*scale));
}
t2D.setColor(color);
//t2D.drawString(t.getText(), x, y);
layout.draw(t2D, x, y);
at.setToRotation(0, x, y);
t2D.setTransform(at);
//This error is to remind you that the Affine transform is not working and the text is in the collection still after it is moved.
}
Below are two images that describe the issue.
Image 1 is the Normal View at Normal Scale
Image 2 is the Alter after Text addition Scale.
If the text is deleted the Scale returns to the first image.
Normal Scale:
Added Text Scale Changes:
I currently have an application that onClick will draw a green bounding rectangle around the battery and the blue strip of paper. I would also like to have the button onClick draw a line from the battery to the strip of paper(as shown in second picture below). Currently I am able to get the all the x and y values of the rectangles, thus knowing that I need to draw a line from 534,1261 to 788,1261 and have the line labeled with the x difference as shown in picture.
For drawing lines and text You can use code like that:
Point firstPoint = new Point(100, 200);
Point secondPoint = new Point(100, 400);
Point middlePoint = new Point(firstPoint.x,
firstPoint.y + 0.5 * (secondPoint.y - firstPoint.y));
Scalar lineColor = new Scalar(255, 0, 0, 255);
int lineWidth = 3;
Scalar textColor = new Scalar(255, 0, 0, 255);
Imgproc.line(sourceMat, firstPoint, secondPoint, lineColor, lineWidth);
Imgproc.putText(sourceMat, " Text" , middlePoint,
Core.FONT_HERSHEY_PLAIN, 1.5 , textColor);
Where sourceMat - Mat with image.
And for determining of line "height" in cm (approximately) You should use "height" of battery rectangle :
lineHeightCm = 4.46 / heightOfBatteryRectangleInPixels * lineHeightInPixels;
where 4.46 - "height" of AAA battery in cm.
I'm working on a 3D project in JavaFX 8. I have built a Car 3d Model with several TriangleMesh objects I'm also using several other JavaFX 'Shape 3D's to create the wheels and axles.
The problem is that the MeshViews elements seem transparent. I can see the other Shape3D objects thru it
2 Cylinders are visible even though the MeshView is in front of it
Here is an example of one of the TriangleMesh's I made
// ============================= ROOF ============================= //
TriangleMesh roofMesh = new TriangleMesh(VertexFormat.POINT_TEXCOORD);
roofMesh.getPoints().addAll(
/* X */ -roofWidth/2.f, /* Y */ roofHeight + wheelDiameter / 2 + wheelGap + doorHeight, /* Z */ - roofLength/2, //PT0
/* X */ roofWidth/2.f, /* Y */ roofHeight + wheelDiameter / 2 + wheelGap + doorHeight, /* Z */ - roofLength/2, //PT1
/* X */ -roofWidth/2.f, /* Y */ roofHeight + wheelDiameter / 2 + wheelGap + doorHeight, /* Z */ roofLength/2, //PT2
/* X */ roofWidth/2.f, /* Y */ roofHeight + wheelDiameter / 2 + wheelGap + doorHeight, /* Z */ roofLength/2 //PT3
);
roofMesh.getTexCoords().addAll(
0, 0, // t0
1, 0, // t1
0, 1, // t2
1, 1 // t3
);
roofMesh.getFaces().addAll(
1,1, 0,0,2,2,
3,3, 1,2 ,2,1
);
After Creating the mesh I'm creating a new MeshView object
meshViewMap.put("roof", new MeshView(roofMesh));
I have also applied a Material to the MeshViews:
private void setTexColor(Shape3D shape, Color c, String imagePath )
{
PhongMaterial pm = new PhongMaterial();
pm.setDiffuseColor(c);
pm.setSpecularColor(c);
shape.setMaterial(pm);
}
These are the Cylinder that you can see in the image:
//Create Axles
Cylinder frontCylinder = new Cylinder(0.5, bodyWidth);
Cylinder rearCylinder = new Cylinder(0.5, bodyWidth);
PhongMaterial cylinderMat = new PhongMaterial();
cylinderMat.setDiffuseColor(Color.BLACK);
cylinderMat.setSpecularColor(Color.BLACK);
frontCylinder.setMaterial(cylinderMat);
rearCylinder.setMaterial(cylinderMat);
frontCylinder.setRotate(90);
rearCylinder.setRotate(90);
frontCylinder.setTranslateZ( 0.7f * (bodyLength/2 + hoodLength/2));
rearCylinder.setTranslateZ( -0.4f * (bodyLength/2 + hoodLength/2));
frontCylinder.setTranslateY(wheelDiameter/2);
rearCylinder.setTranslateY(wheelDiameter/2);
this.getChildren().add(frontCylinder);
this.getChildren().add(rearCylinder);
I have tried to set the opacity to 1 even though it is the default value.
Java Version 8.0.121-b13
By default, a JavaFX Scene doesn't include a depth buffer. When used for 3D, this may result in weird Escherian artifacts where objects or surfaces farther from the camera are drawn on top of those closer to the camera.
An application may request depth buffer support or scene anti-aliasing support at the creation of a Scene. A scene with only 2D shapes and without any 3D transforms does not need a depth buffer nor scene anti-aliasing support.
To enable the depth buffer, use one of the constructors that takes a boolean depthBuffer argument.
For a SubScene, the corresponding constructor also requires a SceneAntialiasing argument. (The default value would be SceneAntialiasing.DISABLED.)
(Based on Fabian's comment, for those who don't look closely at comments.)
I had a problem programming my first Minecraft Mod.
Here is the source code:
Events.java:
public class Events {
#SubscribeEvent
public void onRenderGameOverlay(RenderGameOverlayEvent event) {
if(!event.isCancelable() && event.type == ElementType.EXPERIENCE && !Minecraft.getMinecraft().thePlayer.capabilities.isCreativeMode) {
int posX = event.resolution.getScaledWidth() / 2 + 10;
int posY = event.resolution.getScaledHeight() - 48;
Minecraft.getMinecraft().renderEngine.bindTexture(new ResourceLocation("tc:textures/gui/thermo-icon.png"));
Minecraft.getMinecraft().ingameGUI.drawTexturedModalRect(posX + 9, posY + 3, 0, 9, 71, 3);
}
}
}
So, my problem is that in Minecraft it shows me this:
Note the red ellipse (I added it with GIMP), inside it there is a black rectangle (I haven't added it with GIMP)... it is too small and without texture...
I followed this tutorial (https://www.youtube.com/watch?v=oi41BAlRjtE), but still not working...
Any solution, please?
UPDATE - - - - - -
Thanks all guys for help, I understood that height = 3 pixel is too small... But now I've one more problem...
The light grey rectangle in the center, should be a
square, and the black part should be a "circle".
Does anyone know the cause of the wrong proportions? Thanks!
Too small?
What size were you expecting?
drawTexturedModalRect(posX + 9, posY + 3, 0, 9, 71, 3);
Is it not 71 pixels long and 3 tall... just what you provided? Its hard to tell. Maybe the texture is working but you are offseting it by 9 pixels(when you only draw 3 pixels of it), but it looks like you are using bindTexture wrong. It takes an int returned from getTexture.
int i = mc.renderEngine.getTexture("/Items/GUI/mixer.png");
GL11.glColor4f(1.0F, 1.0F, 1.0F, 1.0F);
mc.renderEngine.bindTexture(i);
There is a nice wiki / tutorial on doing the sort of mods you are doing that might help : http://www.minecraftforge.net/wiki/Gui_Overlay#Mod_Code
I am trying to draw a 3D tile grid that can be rotated and elevated.
The grid though, when rotated sometimes, does not show the graphics as it should, and mutilates them. The regular grid should look nothing like this.
The top half should not be present.
Can anyone help explain or give examples as to what may be causing this issue?
Just found something else: When you see the spike appear, on one side of your screen, on the opposite, that tile is missing. :
I found that if you set azimuth to 133, elevation to 324, zmod to -0.9, leave xmod at 0 and change the grid to 7 × 7 instead of 10 × 10, then only one single point 'misbehaves'. For this one misbehaving point, we have:
i = 48, j = 3,
x0 = 7.0, y0 = 0.0, z0 = 6.1,
x1 = -0.31273127, y1 = 5.4544506, z1 = -7.5074077,
near = 6.0 and nearToObj = 1.5,
just before the following two lines:
x1 = x1 * near / (z1 + near + nearToObj);
y1 = y1 * near / (z1 + near + nearToObj);
The critical thing here is that z1 + near + nearToObj has crossed below zero. As it crossed below zero, it caused the sign of the values of x1 and y1 calculated by the above two lines to change. This sign change is what causes the grid to appear wrong.
I'm no expert in 3D graphics, but I believe this outcome suggests that you can't plot the point in question because it has gone behind the camera. I'm afraid I'm not sure what the best way to solve this problem would be - that would require more knowledge of 3D graphics than I have.
As for my other answer, it was totally wrong, so I've deleted it. If I was going to claim that the Java 2D graphics API was any doing wrapping using 16-bit integers, I could at least have tried to verify that
g.drawLine(30, 30, 60, 60);
and
g.drawLine(30, 30, 60 + 65536, 60 + 65536);
produced the same output. They do not.
What's (new BasicStroke(6 / 5)) supposed to do?
6 / 5 is a fancy way to write 1.
$ cat Int.java
class Int {
public static void main(String args[]) {
System.out.println("6 / 5 == " + (6 / 5));
return;
}
}
$ make Int.class
javac Int.java
$ java Int
6 / 5 == 1
$