graphische Ausgabe zu langsam (vsync gzielt abschaltbar?)...

Destroyer

Mitglied
Hallo zusammen,
ich plane ein kleines Spielchen in java zu schreiben. Zur Zeit sieht man allerdings nur ein paar Monochrome Bälle rumspringen.....
Ich bin auf folgendes Problem gestoßen: Ich benutze im Spielemodus die Tripple-buffered Technik. Zumindest unter Windows verhalten sich die Grafikroutinen, als ob sie synchronisiert werden. Die Ausgabe ist langsam, obwohl der prozessor fast nix zu tun hat. Der Speicher wird auch kaum belastet.
Eigentlich sollte die Grafik im Hintergrund eingezeichnet werden und dann sollte das System bei passender Gelegenheit flackerfrei umschalten. Scheint aber, als ob die Grafikroutinen auch beim Einzeichnen in den gerade nicht sichtbaren Grafikseiten den vsync berücksichtigt. So wies aussieht schaffe ich maximal 30 FPS, möchte aber schon auf 60 FPS.
Mir wäre schon geholfen, wenn man den vsync gezielt ab und einschalten könnte.
Gibts da ne Möglichkeit?
Gruss
Bastler
 

Destroyer

Mitglied
Ich benutze ein canvas. Dort werden in der Demo mit fillOval(...) Bälle bzw. Kreise animiert.

Hier die Demoklasse (die anderen Klassen wären hier zu länglich, ich denke aber man kann das so auch schon ganz gut verstehen):

public class CollisionBallsDemo {

GraphicKernel gk;
TaskSheduler ts;

public static void main(String args[]) {
CollisionBallsDemo bballs = new CollisionBallsDemo();
bballs.bump();
}

public CollisionBallsDemo() {

// erzeuge GraphicKern (Canvas)
gk = GraphicKernel.createGraphicKernel(400, 300, gk.BUFFER_STRATEGY);
// gk = GraphicKernel.createGraphicKernel(300, 300, gk.BUFFERED_IMAGE);
// gk = GraphicKernel.createGraphicKernel(400, 300, gk.DOUBLE_CANVAS);
gk.setBackground(Color.gray);
gk.setForeground(Color.yellow);

// erzeuge Fenster
JFrame f = new JFrame("Balldemo");
f.getContentPane().add(gk);
f.setSize(gk.getWidth(), gk.getHeight());
f.setVisible(true);

// Anwendung auf "X" schließen
f.setDefaultCloseOperation(f.EXIT_ON_CLOSE);

// erzeuge Puffer für flackerfreie Darstellung NACHDEM das GrafikFenster
// sichtbar ist
gk.createBuffer();

// erzeuge TaskSheduler
ts = new TaskSheduler();
ts.setTimeWait(15);

// registriere Aufgabe, die nach Abschluss eines Umlaufs ausgeführt wird
ts.setEndAction(new GraphicKernelEndAction(gk));
}

void bump() {
// erzeuge Bälle mit Zufallswerten
for (int i = 0; i < 50; i++) {

double x=(Math.random() * gk.getWidth());
double y=(Math.random() * gk.getHeight());
double vx= Math.random() * 10 + 1;
double vy= Math.random() * 10 + 1;
int radius = 10;

BumpingBall bb = new BumpingBall(gk, x, y, vx, vy, radius);

ts.add(bb); // Ball zu TaskSheduler hinzufügen

}
ts.start(); // TaskSheduler laufen lassen
}


class BumpingBall extends CircleBoundedGameObject {

double xa,ya,vx,vy;

final static double g = 9.81f;

public BumpingBall(GraphicKernel gk, double x, double y, double vx, double vy, int radius) {
super(gk, radius);
setX(x);setY(y);
this.vx=vx;
this.vy=vy;
}


public void work() {

Graphics bg = gk.getBufferGraphics(); // hole aktuellen GrafikPuffer
bg.setColor(gk.getForeground());
bg.fillOval((int) getX(),(int) getY(),(int) getRadius(), (int) getRadius());

// Orientierung bei überschreiten des Randes ändern
double xMin=0;
if (getX() < xMin) {
setX(xMin);
vx=-vx;
}
double xMax=gk.getWidth()-getRadius();
if (getX() > xMax) {
setX(xMax);
vx=-vx;
}
double yMin=getRadius();
if (getX() < yMin) {
//y= yMin;
//vy=-vy;
}
double yMax=gk.getHeight()-getRadius();
if (getY() > yMax) {
setY(yMax);
vy=-vy;
}
// Bewegung berechnen
vy += g * 0.1; // gleichmäßig beschleunigt: v=a*t + v0
setX(getX() + vx); // gleichförmige Bewegung : s=v*t + s0
setY(getY() + vy);

// Schnitt dieses Objektes mit allen anderen Objekten berechnen

}
}
}
 

Blender3D

Top Contributor
Hier die Demoklasse (die anderen Klassen wären hier zu länglich, ich denke aber man kann das so auch schon ganz gut verstehen):
Für die Framerate und eine ruckelfreie Darstellung ist der Gameloop zuständig. Der befindet sich wohl bei Dir in der Klasse GraphicKernel.
Wenn Du alles richtig machst sollten auch Frameraten über 100 fps kein Problem darstellen.
Hier zum probieren ein Asteroidclone in Java zum probieren er läuft mit 80 fps.
https://www.java-forum.org/thema/spielesammelthread.123839/#post-1288802
 

Destroyer

Mitglied
Hmm, so ähnlich schnell habe ich es mir vorgestellt.
Tut wohl nicht so viel zur Sache, aber die gameloop liegt im TaskSheduler und wird mit setTaskSheduler(15) auf 15 ms eingestellt.
D.h. der Tasksheduler ruft alle registrierten gameobjekte einmal auf und verzögert dann auf 15 ms. Dannach wiederholt sich der Aufruf.
Dauert die Abarbeitung länger als 15ms, so wartet er halt nicht.
Ich hab das ohne Grafik getestet und es funktioniert wie erwartet. Es sollte hier zu 66,66 Aufrufen pro Sekunde kommen. Allerdings dauert die Abarbeitung der graphischen Aufgaben offenbar länger.
Der Prozessor und Festplatte langweilen sich aber, was bedeutet, dass die Synchronisation Probleme bereitet. Nun ja, denke ich jedenfalls.
Kann es sein, daß die nativen graphikmethoden, die von java aufgerufen werden, auch dann im vsync arbeiten, wenn der Grafikbereich gar nicht sichtbar ist? Z.B. wenn man in einem ImmageBuffer arbeitet?

Würde man unter Linux X nicht startet, so arbeiten die Standart Grafikroutinen von java NICHT. Also z.B. generieren einer Grafik in einem Immagebuffer, um von dort eine Druckerdatei zu generieren, funktioniert nicht. Na ja, da werden eben unter anderem native Methoden vom X benutzt.

Nur so am Rande:
Der GraphicKernel hat eine Abstraktion zur Änderung der Basistechnik: Die einkommentierte Variante nutzt die Java api direkt, tripplebuffered eingestellt.
Bei einer anderen Technik wähle ich ein doppelt tiefes Canvas (Grafik nach unten erweitert), stelle aber nur den ersten Teil dar.
Eingezeichnet wird im nicht sichtbaren Teil und zum gegebenen Zeitpunkt in den sichbaren bereich kopiert. Daher sollten die Operationen fast ausschließlich im Grafikram arbeiten.
Die dritte Variante benutzt einen Immagebuffer fürs gleiche Spiel. D.h. es wird in einen Immagebuffer, welcher im normalen RAM liegt, gezeichnet und der zum gegebenen Zeitpunkt in das sichtbare canvas, also in den Speicher der Grafikkarte, kopiert.
(Ok, kann bei den Rechnern auch schon sein, dass der Graifkspeicher im normalen RAM liegt)
Keine der Techniken führt bei mir zu zufriedenstellenden Ergebnissen. Man sieht aber, dass der Prozessor bei den selbstgefrickelten Varaianten (durchs kopieren denke ich) stärker belastet wird, als bei der java-inline Technik.
 

Blender3D

Top Contributor
Keine der Techniken führt bei mir zu zufriedenstellenden Ergebnissen. Man sieht aber, dass der Prozessor bei den selbstgefrickelten Varaianten (durchs kopieren denke ich) stärker belastet wird, als bei der java-inline Technik.
Da wir hier keinen relevanten Code zu Gesicht bekommen fällt eine Stellungnahme bis auf Weiteres dazu aus.
 

Destroyer

Mitglied
Das sollte so nicht sein. Der Rechner tastet den sichtbaren Bereich zur Darstellung aber häufig ab. Bei hd 60 mal pro Sekunde. Während des Auslesens darf man auf den Speicher zumindest nicht schreibend zugreifen, sonst kommt es zu Grafikfehlern. Daher machen das die nativen Routinen wohl normalerweise im vsync. (Wenn getastet wird, nix einzeichnen). Das führt halt zu empflindlichen Verzögerungen. Auch würde man unter Beachtung des Ausleseprozesses vom System manches nicht am Stück durchführen können. Z.B. Linie von unten nach oben Zeichen. Zumindest bei Ausgabe a la svga wird im speicher von oben nach unten getastet. Das heißt man "schneidet" den Aufbau fast zwangsläufig. Also so was aufteilen und selbst dann würde man ein "Applikationsflackern" erkennen können, da einheitliche Elemente nicht während eines Bildschirmtastens=Bildschirmaufbau vom Monitor gleichzeitig erscheinen.
Führt halt zur "double-buffer" Technik. Man zeichnet gemütlich im nicht Sichtbaren bereich. Die Hardeware kann z.B. das Sichtfenster umschalten, wenn gerade nicht getastet wird. Manch eine Hardware kopiert auch die Seiten. (java hat da einige Basisklassen, aus denen man solche Details rauszirbeln kann). Ist fast egal, wie man in den Puffer einzeichnet, es bleibt daher flackerfrei. Auch ist das Produzieren der Grafik von den lästigen Synchronisieren des Ausgabespeichers fast vollständig entkoppelt.
Jedenfalls sollte man sich darum nicht kümmern müssen, außer dem Einstellen der Technik. :rolleyes:
 

Blender3D

Top Contributor
D.h. der Tasksheduler ruft alle registrierten gameobjekte einmal auf und verzögert dann auf 15 ms. Dannach wiederholt sich der Aufruf.
Dauert die Abarbeitung länger als 15ms, so wartet er halt nicht.
Das Update der Gameobjekte sollte im Gameloop direkt erfolgen.
Danach das Zeichnen.
Die dafür benötigte Zeitspanne sollte von der von der gewünschten Wartezeit abgezogen werden.
Im Fall einer zu langen Wartezeit müssen die verlorenen Updates ohne Zeichnen nachgeholt werden und ein Zähler für diesen verlorenen Frame erhöht werden. Alle ca. 16 verlorenen Frames sollten andere Prozesse die Möglichkeit gegeben werden zu laufen.
Java:
Thread.yield()
Regeln für eine flüssige Darstellung:
1) Vermeide möglichst zusätzliche Threads.
2) Kontrolliere die gewünschte Wartezeit
z.B. 100 fps --> 10 ms Wartezeit
Wartezeit = Wartezeit - Dauer für das Update - Dauer für das Zeichnen.
Bei einer Überzeit führe die verlorenen Updates ohne Zeichnen aus und gib den Prozess ab und an an die Systemprozesse (Tastatur, Mouse, ..) ab.
3) Vermeide unnötige Erzeugung von Objekten.
z.B. eine finale Klasse Vektor für die Koordinate der Spielobjekte die 100 mal pro Sekunde pro Spielobjekt erzeugt wird ( new Vektor(x,y) ) ist durch v.x = neuePosition v.y = neuePosition zu ersetzen. Ich habe bei dem Asteroid Clone eine Spriteklasse verwendet die im Gameloop mit s.move() die Bewegung des Spielobjekts realisiert.
4) aktives Rendern --> kein repaint()
 

Destroyer

Mitglied
Vieles was ich zu wissen glaube, nur die Antwort kenne ich nicht o_O
Denke ich muss mal sehr genau abchecken, wo die Zeit eigentlich verloren geht. An der Rechenpower liegts mal nicht.
Kennt jemand vielleicht einen guten "strace"? Ich möchte feststellen, was das System zeitlich so treibt.
 

Blender3D

Top Contributor
Denke ich muss mal sehr genau abchecken, wo die Zeit eigentlich verloren geht. An der Rechenpower liegts mal nicht.
Weder an der Rechenpower noch an Java was der Asteroidclone unter Beweis stellt. Der läuft bei mir auch auf einen i3 Laptop Baujahr 2010 unter Ubuntu sehr flüssig.
Wie gesagt du brauchst dich lediglich an die Vorgaben von Post #9 halten. Ein Tipp noch dazu: Bau dir eine Anzeige für die Framerate ein. Dadurch erkennt man während der Entwicklung eines Spiels, wann es zu Problemen mit der Geschwindigkeit kommt.
 

Destroyer

Mitglied
Ja, es ist schon viel länger her. Hab den Fehler nicht finden können....
Also ich tat nun, wie du mir geheißen hast. Hab eine Anzeige für die Framerate eingebaut. Jedenfalls jetzt läuft die Demo spielend mit 60hz. Entdrosselt sinds bei mir ca 1300hz. Das heißt, ich kann der Sache eine weitere Chance geben.
Weiss leider nicht, woran es gelegen hat. Entweder hat meine Debugausgabe (die ging auf die Konsole) Probleme gemacht, oder aber sie war kurzerhand falsch. Die neue Anzeige mißt unabhängig vom TaskSheduler (mainloop).
Mein Rechner hat diverse updates erhalten, könnte vielleicht auch das Problem gelößt haben.

Man sieht aber, dass die volle Framerate nicht dargestellt wird. Na ja, der Monitor hat natürlich auch seine Beschränkungen.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
G 2D-Slider bzw. eine graphische Auswahlkomponente die sich so verhält AWT, Swing, JavaFX & SWT 6
K Graphische Oberflächen in Java? AWT, Swing, JavaFX & SWT 2
L Graphische Webapplikation: Blättern in einem Buch? AWT, Swing, JavaFX & SWT 3
F Wer wäre bereit mir zu helfen?Programmierstil graphische Obf AWT, Swing, JavaFX & SWT 4
A Graphische Auswertungen AWT, Swing, JavaFX & SWT 4
B rohling für graphische benutzeroberfläche? AWT, Swing, JavaFX & SWT 2
E Wie heißt dieses graphische Element (Bild inside)? AWT, Swing, JavaFX & SWT 2
D Hohe Prozessorauslastung bei Ausgabe auf TextArea AWT, Swing, JavaFX & SWT 2
P GUI Ausgabe des Strings AWT, Swing, JavaFX & SWT 3
S Ausgabe aktualisiert sich nur nach 2. Klick AWT, Swing, JavaFX & SWT 17
ralfb1105 JavaFX MVC: Thread in Model Class mit Ausgabe in TextArea AWT, Swing, JavaFX & SWT 10
F JavaFX textField Ausgabe automatisch kopieren AWT, Swing, JavaFX & SWT 7
S Ausgabe in JTextArea AWT, Swing, JavaFX & SWT 13
R Ausgabe über JOptionPane.showMessageDialog funktioniert nicht AWT, Swing, JavaFX & SWT 2
M Ausgabe der HSL oder RGB Zusammensetzung einer Farbe (JColorChooser AWT, Swing, JavaFX & SWT 1
N Swing Jtextfield und Ausgabe von Wärungsbeträgen AWT, Swing, JavaFX & SWT 3
KilledByCheese Swing Seltsame Ausgabe nach ButtonClick AWT, Swing, JavaFX & SWT 1
P JavaFX Komische konsolen Ausgabe (nur roter Pfad) AWT, Swing, JavaFX & SWT 7
D Swing Warum erhalte ich keine Ausgabe? Funktioniert der equals-vergleich in actionPeformed nicht richtig? AWT, Swing, JavaFX & SWT 3
L Ausgabe in JEditorPane mittels HTMLEditorKit zeigt auf bestimmten Systemen falsche Zeichen AWT, Swing, JavaFX & SWT 1
H Swing jComboBox Ausgabe -1/null AWT, Swing, JavaFX & SWT 4
A Swing Zwei Klassen mit Textfeld Eingaben vergleichen und Ausgabe erzeugen AWT, Swing, JavaFX & SWT 10
A Swing 2 JSlider verknüpfen und mit einem JTextField vergleichen, dann Ausgabe AWT, Swing, JavaFX & SWT 5
X JTextField Ausgabe klappt nicht AWT, Swing, JavaFX & SWT 4
A Swing Focus der Radio Buttons + text bleibt gleich und gleichzeitige ausgabe zweier Objekte in 1. Fenster AWT, Swing, JavaFX & SWT 3
T Swing Ausgabe aus ArrayList in Klasse1 in jTextArea in Klasse2 AWT, Swing, JavaFX & SWT 2
L Schöne Ausgabe in Form einer Liste AWT, Swing, JavaFX & SWT 5
E Keine Ausgabe auf Console und List AWT, Swing, JavaFX & SWT 13
J Swing Ausgabe in JTable AWT, Swing, JavaFX & SWT 3
J Swing Ausgabe in einem JFrame AWT, Swing, JavaFX & SWT 8
S String Array Ausgabe im JLabel ??? AWT, Swing, JavaFX & SWT 8
E Keine Ausgabe von JList bei drücken von Button auf die Konsole AWT, Swing, JavaFX & SWT 7
P Ausgabe Label AWT, Swing, JavaFX & SWT 6
D Fenster will keine Ausgabe geben>:( AWT, Swing, JavaFX & SWT 3
kniffel Ausgabe von leeren JTable Zeilen AWT, Swing, JavaFX & SWT 3
C TextArea Ausgabe immer ganz oben AWT, Swing, JavaFX & SWT 3
S TextArea ausgabe ohne JFrame zu implementieren AWT, Swing, JavaFX & SWT 2
M Swing Ausgabe in JTextArea verzögern AWT, Swing, JavaFX & SWT 7
R JComboBox Ausgabe in String speichern AWT, Swing, JavaFX & SWT 3
H Swing Ausgabe auf 2 nachkomma stellen beschränken AWT, Swing, JavaFX & SWT 3
B Ausgabe schrittweise AWT, Swing, JavaFX & SWT 13
D Vollbild ausgabe AWT, Swing, JavaFX & SWT 2
M Swing Probleme bei der Ausgabe der JList AWT, Swing, JavaFX & SWT 2
J Swing Swing Ein/Ausgabe von einem Datum AWT, Swing, JavaFX & SWT 3
H Ausgabe an Textfeld JTextField AWT, Swing, JavaFX & SWT 3
W Welche Text ausgabe möglichkeit ist geeignet... AWT, Swing, JavaFX & SWT 6
S Tabellen und Text Ausgabe in Swing GUI AWT, Swing, JavaFX & SWT 3
Z GUI-Ausgabe mit Bild und Sound AWT, Swing, JavaFX & SWT 3
M Ausgabe nach Klick auf JButton funktioniert nicht. AWT, Swing, JavaFX & SWT 6
D JTable Viewport - Ausgabe der sichtbaren Spalten AWT, Swing, JavaFX & SWT 2
F dynamische Ausgabe eines extenen Programms umleiten AWT, Swing, JavaFX & SWT 6
J Bildfilterung und Ausgabe in ein ImageIcon AWT, Swing, JavaFX & SWT 2
S Dynamische Ausgabe im JTextField AWT, Swing, JavaFX & SWT 7
L Problem bei der Ausgabe JTextArea AWT, Swing, JavaFX & SWT 3
S Eingeschränkte Ausgabe auf 2. Bildschirm? (Laptop VGA Output AWT, Swing, JavaFX & SWT 4
P SWT Performance : "Text" - Ausgabe beschleunigen ? AWT, Swing, JavaFX & SWT 21
G Aktualisierung der Ausgabe in SWT AWT, Swing, JavaFX & SWT 2
Z Die ausgabe.setText(b.getisbn()); überschreibt sich jedesmal AWT, Swing, JavaFX & SWT 4
E Frage? Warum funktioniert die grafische Ausgabe nicht? AWT, Swing, JavaFX & SWT 4
J DB-Ausgabe realisieren? AWT, Swing, JavaFX & SWT 2
M Ausgabe mit JOptionPane AWT, Swing, JavaFX & SWT 6
G Bedingte Ausgabe beim JTree AWT, Swing, JavaFX & SWT 4
M Konsolenprg-Ausgabe in GUI geleitet - Brauche ich Threads? AWT, Swing, JavaFX & SWT 2
V JTree Children Ausgabe Problem AWT, Swing, JavaFX & SWT 2
V Tree Ausgabe Problem AWT, Swing, JavaFX & SWT 2
E Java-TexturePaint sehr langsam AWT, Swing, JavaFX & SWT 9
Tommy135 JFileChooser ist sehr langsam AWT, Swing, JavaFX & SWT 13
M Swing GUI wird nach invokeLater() langsam AWT, Swing, JavaFX & SWT 19
D JavaFX GUI Komponenten werden langsam bei größerer Datenmenge AWT, Swing, JavaFX & SWT 6
J JavaFX Rendering von Canvas sehr langsam AWT, Swing, JavaFX & SWT 2
C Swing GUI extrem langsam - GUI-Code richtig ausführen AWT, Swing, JavaFX & SWT 1
L [Slick2d] Sidescroller/Hintergrundbild sehr langsam AWT, Swing, JavaFX & SWT 3
S Swing JtextPane sau langsam AWT, Swing, JavaFX & SWT 15
P JFrame langsam / seltsames Verhalten AWT, Swing, JavaFX & SWT 6
X JInternalFrame vor Java2D-Zeichnung langsam bzw. Gui friert ein AWT, Swing, JavaFX & SWT 1
H Swing JScrollPane mit "viel Inhalt" scrollt zu langsam (inkl. See-For-Yourself.jar :D) AWT, Swing, JavaFX & SWT 2
D Image soll langsam sichtbar werden AWT, Swing, JavaFX & SWT 4
M JTable mit wechselnden Spalten - sehr Langsam AWT, Swing, JavaFX & SWT 5
A HELP: JFieldText dynamisch setzen -> langsam AWT, Swing, JavaFX & SWT 19
O RandomAccesFile langsam AWT, Swing, JavaFX & SWT 6
lumo AWT Screenshots machen ist langsam? AWT, Swing, JavaFX & SWT 6
P 2D-Grafik g2.drawImage() langsam AWT, Swing, JavaFX & SWT 110
J JApplet langsam wegen vielen Tooltips? AWT, Swing, JavaFX & SWT 36
R Image laden sehr langsam AWT, Swing, JavaFX & SWT 7
F Swing JTable langsam AWT, Swing, JavaFX & SWT 13
Kr0e VolatileImage langsam AWT, Swing, JavaFX & SWT 10
A repaint() zu langsam, bitte um alternativen AWT, Swing, JavaFX & SWT 5
A Swing JTextPane sehr langsam AWT, Swing, JavaFX & SWT 6
R TableRowSorter... zu langsam AWT, Swing, JavaFX & SWT 9
Stillmatic JTextPane langsam? AWT, Swing, JavaFX & SWT 5
R JTable für sehr viele Daten sehr langsam AWT, Swing, JavaFX & SWT 20
PAX JList aktualisiert zu langsam beim Hinzufügen von Einträgen AWT, Swing, JavaFX & SWT 6
G JScrollPane scrollt zu langsam AWT, Swing, JavaFX & SWT 6
S Bilder werden sehr langsam geladen AWT, Swing, JavaFX & SWT 4
M jFileChooser extrem langsam AWT, Swing, JavaFX & SWT 15
G Swing Programmstart zu langsam AWT, Swing, JavaFX & SWT 3
J JFileChooser öffnet sich in manchen Fällen extrem langsam! AWT, Swing, JavaFX & SWT 12
D Scrollbalken zu langsam AWT, Swing, JavaFX & SWT 10
S Programm aufgrund von paint() zu langsam AWT, Swing, JavaFX & SWT 18
doctus img.getScaledInstance() sehr rechenintensiv und langsam? AWT, Swing, JavaFX & SWT 3

Ähnliche Java Themen

Neue Themen


Oben