Trotz Antialiasing zu verpixelt

_-`avaj´-_

Mitglied
Hallo erstmal an alle!
Ich versuche seit längerem ein Spiel zu programmieren: Stick Wars
Das Spiel gibt es schon und ich finde es klasse, deshalb möchte ich es gerne selber programmieren und ausbauen...

Link:
http://www.stickpage.com/stickwargameplay.shtml

Da das Spiel nicht aus Strichmännchen im eingetlichem Sinn besteht (also nur aus Strichen) sondern aus 2 dimensionalen nun ja... Strichen :) werde ich mine Strichmännchen aus Polygonen basteln.
So weit so gut. Damit das alles funktioniert muss ich die Stricke auch drehen können... Das klappt auch wunderbar aber sobald ich das mache wird das ganze sehr verpixelt, obwohl ich Antialiasing an habe:

pixel.png


Gibt es eine Art in Java "genauer" zu Zeichnen?


@Admin:
Kann ich die Bilddatei bei euch hochladen?
Im Moment hab ich die Datei auf meinem Server hohgeladen und der ist nicht immer online...
 

_-`avaj´-_

Mitglied
Ein Auszug aus meinem JPannel, in dem alles gezeichnet wird:
Also alles was gezeichnet werden muss ist drawable und hat die Methode draw(Graphics g)...
Aber trotz
Code:
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
ist das ganze verpixelt...

Java:
@Override
	protected void paintComponent(Graphics g) {
		Graphics2D g2 = (Graphics2D) g;
		g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		try {
			for (Drawable d : list) {
				d.draw(g2);
			}
		} catch (java.util.ConcurrentModificationException e) {
		}
	}
 
T

tröööt

Gast
naja ... ein monitor hat nun mal pixel die horizontal/vertikal ausgrichtet sind ... und entsprechend wird auch gezeichnet ...

nur wie GENAU das gemacht wird hängt halt von den einstellungen und vor allem der auflösung und der größe des objektes ab ... und selbst SVG hat mit diesem problem zu kämpfen ... denn ein rechner kann es nun mal nicht anders darstellen ...
 
S

Spacerat

Gast
Scheint, als würde die "2-Dimensionale Linie" (also das Rechteck) in der Reihenfolge gezeichnet, antialiased und anschliessend ohne Aliasing vergrössert. Meine Glaskugel ist aber ebenso verpixelt, wie Landei's Kristallkugel verschmiert. Zumindest lässt sich das Aliasing ansatzweise erkennen.
 

_-`avaj´-_

Mitglied
naja ... ein monitor hat nun mal pixel die horizontal/vertikal ausgrichtet sind ... und entsprechend wird auch gezeichnet ...

nur wie GENAU das gemacht wird hängt halt von den einstellungen und vor allem der auflösung und der größe des objektes ab ... und selbst SVG hat mit diesem problem zu kämpfen ... denn ein rechner kann es nun mal nicht anders darstellen ...

Also wenn ich in jedem Spiel solche Pixel hätte würd ich mich aufhängen gehen!
Spass beiseite: Ich meine damit, dass andere es auch hinbekommen dass ihre Grafiken nicht so eckig aussehen...

Scheint, als würde die "2-Dimensionale Linie" (also das Rechteck) in der Reihenfolge gezeichnet, antialiased und anschliessend ohne Aliasing vergrössert. Meine Glaskugel ist aber ebenso verpixelt, wie Landei's Kristallkugel verschmiert. Zumindest lässt sich das Aliasing ansatzweise erkennen.

Ohh sorry, ich hab gedacht das wäre klar: Das rechts ist nur eine Vergrößerung mit der Bildschirmlupe, um es klarer zu machen, wie eckig das Ding ist...

Und wie sieht die
Code:
draw()
aus?

Für dicke Striche brauchst du keine Polygone. Da reichen auch Linien in Verbindung mit [JAPI]BasicStroke[/JAPI].
Siehe dazu: Stroking and Filling Graphics Primitives (The Java™ Tutorials > 2D Graphics > Working with Geometry)

Ich habe gedacht draw() wäre klar... Da wird halt einfach das Polygon gezeichnet:
(x bzw. y sind die Koordinaten jew. in einem Array)

Java:
@Override
	public void draw(Graphics g) {
		g.fillPolygon(x, y, x.length);
	}

Und wegen BasicStroke:
So wie ich das sehe lässt sich das ganze aber nicht drehen... bzw. hat eine x, eine y Koordinate so wie Länge und Breite wie ein Rechteck aber keine 2 Verbindungspunkte oder?
 
Zuletzt bearbeitet:

xehpuk

Top Contributor
Am besten postest du mal ein KSKB. Wo sind die Punkte fürs Polygon? Wo wird gedreht? Etc.
Außerdem fehlt in deiner
Code:
paintComponent()
der Aufruf von
Code:
super.paintComponent()
. Könnte vielleicht schon daran liegen.

Hier ein Beispiel mit gut zu sehendem Antialiasing bei Polygon (schwarz) und Linie (rot):
Java:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

public class Stroking extends JPanel {
	private final int[] xs = {0, 40, 40, 0};
	private final int[] ys = {0, 0, 20, 20};
	
	@Override
    protected void paintComponent(final Graphics g) {
		super.paintComponent(g);
        final Graphics2D g2 = (Graphics2D) g.create();
        g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		g2.setTransform(AffineTransform.getTranslateInstance(20, 10));
		g2.rotate(Math.PI / 10);
		g2.setColor(Color.BLACK);
        g2.fillPolygon(xs, ys, xs.length);
		g2.setTransform(AffineTransform.getTranslateInstance(80, 10));
		g2.rotate(Math.PI / 10);
		g2.setStroke(new BasicStroke(20, BasicStroke.CAP_BUTT, BasicStroke.JOIN_BEVEL));
		g2.setColor(Color.RED);
		final int y = (ys[0] + ys[2]) / 2;
		g2.drawLine(xs[0], y, xs[1], y);
		g2.dispose();
    }
	
	public static void main(final String... args) {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				final JFrame f = new JFrame();
				f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				final Stroking s = new Stroking();
				s.setBackground(Color.WHITE);
				s.setPreferredSize(new Dimension(130, 50));
				f.setContentPane(s);
				f.pack();
				f.setLocationRelativeTo(null);
				f.setVisible(true);
			}
		});
	}
}
Ergebnis:
attachment.php


Falls dir das Transformieren der
Code:
Graphics2D
neu erscheint: Transforming Shapes, Text, and Images (The Java™ Tutorials > 2D Graphics > Advanced Topics in Java2D)
 

Anhänge

  • Antialiasing.png
    Antialiasing.png
    2,1 KB · Aufrufe: 110

Marco13

Top Contributor
Außerdem fehlt in deiner
Code:
paintComponent()
der Aufruf von
Code:
super.paintComponent()
. Könnte vielleicht schon daran liegen.

Das klingt im ersten Moment komisch, könnte aber wirklich sein - insbesondere, wenn mehrfach gezeichnet wird (mit repaint) könnten sich die eigentlich halbtransparenten Pixel vom Antialiasing "aufsummieren" und am Ende wie ungeantialiaste aussehen.
 
S

Spacerat

Gast
Das klingt im ersten Moment komisch, könnte aber wirklich sein - insbesondere, wenn mehrfach gezeichnet wird (mit repaint) könnten sich die eigentlich halbtransparenten Pixel vom Antialiasing "aufsummieren" und am Ende wie ungeantialiaste aussehen.
Glaub' ich weniger, weil "super.paintComponent()" ja aufgerufen wird, bevor das Antialiasing überhaupt gesetzt wird. Kann man aber testen, indem man es halt mal auskommentiert.
 

xehpuk

Top Contributor
Das klingt im ersten Moment komisch, könnte aber wirklich sein - insbesondere, wenn mehrfach gezeichnet wird (mit repaint) könnten sich die eigentlich halbtransparenten Pixel vom Antialiasing "aufsummieren" und am Ende wie ungeantialiaste aussehen.
Japs, genau so war es gedacht. Gerade wenn hier anscheinend so ein Mischmasch aus active und passive rendering (alle x ms
Code:
repaint()
) verwendet wird, die Repaints also programmatisch ausgelöst werden.

Glaub' ich weniger, weil "super.paintComponent()" ja aufgerufen wird, bevor das Antialiasing überhaupt gesetzt wird. Kann man aber testen, indem man es halt mal auskommentiert.
Es ist ja nur zum Leeren des Hintergrunds da. Von daher ist es egal, ob das Antialiasing aktiv ist.

Ich habe das nun auch getestet, indem ich
Code:
super.paintComponent()
auskommentiert und Folgendes der
Code:
main()
hinzugefügt habe:
Java:
new Timer().scheduleAtFixedRate(new TimerTask() {
	@Override
	public void run() {
		s.repaint();
	}
}, 1000, 1000);
In der Tat überlagern sich die transluzenten Antialiasing-Pixel jede Sekunde immer mehr, sodass es am Ende opak wird.

Hier die ersten 100 Zeichnungen:
attachment.php


Die ersten 10 Zeichnungen fünffach vergrößert:
attachment.php
 

Anhänge

  • Antialiasing.gif
    Antialiasing.gif
    47,7 KB · Aufrufe: 78
  • Antialiasing (2).gif
    Antialiasing (2).gif
    35 KB · Aufrufe: 93
Zuletzt bearbeitet:

_-`avaj´-_

Mitglied
Jo genau das war der Fehler!
Auch in mienem Programm sieht das ganze bestens aus nach dem der super-Aufruf da steht!
Ok das das ganze so ein einfacher dummer Fehler ist hätte ich nicht gedacht :D
Aber danke an alle!
 
Zuletzt bearbeitet:
T

tröööt

Gast
Also wenn ich in jedem Spiel solche Pixel hätte würd ich mich aufhängen gehen!
Spass beiseite: Ich meine damit, dass andere es auch hinbekommen dass ihre Grafiken nicht so eckig aussehen...
du musst es nur stark genug vergrößern ... dann siehst du es ...

"kantenglättung" ... um mal das deutsche wort zu nutzen ... ist nichts weiter als das die berechnung der entsprechenden werte der pixel genauer vorgenommen wird ... und man somit den unterschied nicht mehr ganz so krass wahrnimmt ...
würde man aber jedes pixel was auch nur um ein bit vom anderen abweicht in einer anderen farbe darstellen so wäre das ergebnis ungefähr gleich dem beispiel ganz oben ...

es ist nun mal fakt das ein rechner nur mit solch quadratischen pixeln die eine horinzontale/veritkale ausrichtung haben umgehen kann ... und entsprechend sind monitore auch so gebaut diese genau so anzuzeigen ... und daran können auch die besten algorithmen nichts ändern .... sondern nur die darstellung soweit anpassen das es unser "blödes" menschliches auge nicht mehr so direkt wahrnehmen kann ...
 

Oben