Double buffering
1 bericht
• Pagina 1 van 1
Double buffering
Inleiding
Het is je waarschijnlijk wel eens opgevallen dat bij het schrijven van een grafische applicatie het beeld flikkert wanneer de inhoud geüpdate wordt. Dit heeft te maken met de manier van updaten van het scherm.
Ik maak zelf vaak gebruik van Java, waarin ik ook wel eens iets bewegends heb gemaakt, in het simpelste geval een balletje wat heen en weer vliegt door het scherm. Laten we eens kijken naar wat er gebeurd als we een balletje heen en weer laten vliegen over het scherm.
Doordat het scherm eerst wordt leeggemaakt waarna alle objecten opnieuw worden getekend is het scherm een relatief groot deel van de tijd niet compleet, waardoor we flikkeringen zien.
De oplossing
Als we nu in plaats van direct naar het scherm eerst naar een tweede buffer (vandaar de naam doublebuffering) schrijven, en vervolgens die tweede buffer in het scherm stoppen, hebben we niet te maken met halfafgemaakte schermen, omdat het geüpdate scherm in één keer wordt weergegeven.
De implementatie
Toevallig (soms bestaat toeval) was ik gisteren bezig met een vingeroefeningetje in Java. Ik wilde de computer twee batjes laten besturen die een balletje heen en weer mepten.
Dat is niet zo moeilijk, maar het is wel een mooi voorbeeld om te laten zien hoe je in Java doublebuffering kunt toepassen.
Ik zal hieronder een enigszins gewijzigde versie (omgebouwd naar een appletje) weergeven.
JAVA
Omdat ik toevallig ook nog wat c++-code heb liggen van mijn nibblesclone, zal ik ook even de toepassing binnen c++ hier neerzetten. Houd er bij c++ - in tegenstelling tot Java - rekening mee dat je de tweede buffer expliciet moet vernietigen, omdat je anders te maken hebt met een memoryleak van jewelste. (Auteur memoreert aan de eerste testversie van zijn nibblesclone die de computer liet vastlopen...).
In mijn nibblesclone heb ik gebruik gemaakt van windows.h.
C
Het is je waarschijnlijk wel eens opgevallen dat bij het schrijven van een grafische applicatie het beeld flikkert wanneer de inhoud geüpdate wordt. Dit heeft te maken met de manier van updaten van het scherm.
Ik maak zelf vaak gebruik van Java, waarin ik ook wel eens iets bewegends heb gemaakt, in het simpelste geval een balletje wat heen en weer vliegt door het scherm. Laten we eens kijken naar wat er gebeurd als we een balletje heen en weer laten vliegen over het scherm.
- De positie van het balletje wordt geüpdate, dat wil zeggen: de x- en de y-coördinaat worden veranderd.
- Het huidige scherm wordt leeggemaakt.
- Het balletje wordt opnieuw getekend.
Doordat het scherm eerst wordt leeggemaakt waarna alle objecten opnieuw worden getekend is het scherm een relatief groot deel van de tijd niet compleet, waardoor we flikkeringen zien.
De oplossing
Als we nu in plaats van direct naar het scherm eerst naar een tweede buffer (vandaar de naam doublebuffering) schrijven, en vervolgens die tweede buffer in het scherm stoppen, hebben we niet te maken met halfafgemaakte schermen, omdat het geüpdate scherm in één keer wordt weergegeven.
De implementatie
Toevallig (soms bestaat toeval) was ik gisteren bezig met een vingeroefeningetje in Java. Ik wilde de computer twee batjes laten besturen die een balletje heen en weer mepten.
Dat is niet zo moeilijk, maar het is wel een mooi voorbeeld om te laten zien hoe je in Java doublebuffering kunt toepassen.
Ik zal hieronder een enigszins gewijzigde versie (omgebouwd naar een appletje) weergeven.
JAVA
- Code: Alles selecteren
* Pong.java
* ------------
* This class is meant as an example of doublebuffering.
* It is written by Jorn van der Pol.
* Jorn van der Pol hereby disclaims all warranty, either expressed or implied.
*
* Application:
* <applet code="Pong.class" width="400" height="200"></applet>
*/
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Image;
public class Pong extends Applet implements Runnable{
// The second buffer.
Image buffer;
// The graphics object of the second buffer.
Graphics buffergraphics;
// Loads of coordinates.
// x and y coordinates for the ball, y coordinates for the bats, x-velocity, y-velocity, width and height of the applet.
int x, y, l, r, vx = 1, vy = 1, w, h;
// public void init()
// Initializes the applet.
public void init(){
Dimension d = getSize();
w = (int)d.getWidth();
h = (int)d.getHeight();
x = w / 2;
y = h / 2;
l = y;
r = y;
// Create buffer and buffergraphics.
buffer = createImage(w, h);
buffergraphics = buffer.getGraphics();
// Start the thread.
Thread move = new Thread(this);
move.start();
}
// public void run()
// This method runs to provide animation.
public void run(){
Thread th = Thread.currentThread();
while(true){
try{
th.sleep(10);
}
catch(InterruptedException interrupt){
// I am too lazy to do something really cool here.
// So I\'ll just do nothing ;].
}
x += vx;
y += vy;
if(x < 30){
vx = 1;
}
if(x > w - 35){
vx = -1;
}
if(y < 10){
vy = 1;
}
if(y > h - 10){
vy = -1;
}
repaint();
}
}
// public void paint(Graphics g)
// This method redraws the screen.
public void paint(Graphics g){
// Empty the buffer.
buffergraphics.clearRect(0, 0, w, h);
// Draw two lines.
buffergraphics.setColor(Color.black);
buffergraphics.drawLine(50, 0, 50, h);
buffergraphics.drawLine(w - 50, 0, w - 50, h);
if(vx == -1){
l = y;
}
else{
r = y;
}
// Draw the bats.
buffergraphics.fillRect(20, l - 20, 5, 40);
buffergraphics.fillRect(w - 25, r - 20, 5, 40);
// Draw the ball.
buffergraphics.setColor(new Color(255, 0, 0));
buffergraphics.fillOval(x, y, 10, 10);
// Draw the buffer to the screen.
g.drawImage(buffer, 0, 0, this);
}
// public void update(Graphics g)
// This method is called automatically everytime repaint() is called.
// Override it to prevent the screen from being emptied.
public void update(Graphics g){
paint(g);
}
}
Omdat ik toevallig ook nog wat c++-code heb liggen van mijn nibblesclone, zal ik ook even de toepassing binnen c++ hier neerzetten. Houd er bij c++ - in tegenstelling tot Java - rekening mee dat je de tweede buffer expliciet moet vernietigen, omdat je anders te maken hebt met een memoryleak van jewelste. (Auteur memoreert aan de eerste testversie van zijn nibblesclone die de computer liet vastlopen...).
In mijn nibblesclone heb ik gebruik gemaakt van windows.h.
C
- Code: Alles selecteren
HWND hwnd; // The window that is to be drawn.
// Create a devicecontext.
PAINTSTRUCT ps;
HDC dc = BeginPaint(hwnd, &ps);
// Create a buffer devicecontext.
HDC bufferdc = CreateCompatibleDC(xdc);
// Create a buffer.
HBITMAP buffer = CreateCompatibleBitmap(dc, client.right, client.bottom);
// Select the buffer into the buffer devicecontext.
SelectObject(bufferdc, bmp);
// Do some drawing.
MoveToEx(bufferdc, 50, 50, NULL);
LineTo(bufferdc, 100, 100);
// Draw the buffer to the screen.
// client.right indicates the width of hwnd.
// client.bottom indicates the height of hwnd.
BitBlt(dc, 0, 0, client.right, client.bottom, bufferdc, 0, 0, SRCCOPY);
// Destroy all stuff.
DeleteDC(bufferdc);
DeleteObject(buffer);
EndPaint(hwnd, &ps);'));
- RedRose
- Globale moderator
- Berichten: 1994
- Geregistreerd: 14 Jun 2005 18:12
1 bericht
• Pagina 1 van 1
Wie is er online?
Gebruikers in dit forum: Geen geregistreerde gebruikers en 1 gast