Orangy Tang
|
 |
«
Posted
2011-11-05 00:21:13 » |
|
Right, I'm about to give up on this, but maybe one of you lot can figure this out - I cannot create a non-trivial applet that doesn't flicker something awful at seemingly random intervals. Here's a few links: 1. Albion2. Test 23. Test 3All of these will flicker for me, in both Safari and Chrome on OSX. Some more than others - Albion appears to be the most stable. Albion is using a BufferStrategy created on a Canvas inside a JApplet. Test 2 internally draws onto a BufferedImage, then uses a class derived from Canvas to display that backbuffer. Again, inside a JApplet. Test 3 is cribbed from Oracle's applet example, and draws to an image backbuffer, then to a custom JPanel inside a JApplet. Points of interest: - Chrome flickers much worse, but Safari also flickers. - All of these are rock solid in AppletViewer. - The flicker colour is very odd. It's sometimes the background colour of the Canvas/JPanel. It's not the background colour of the applet tag. But it is sometimes the background colour of the webpage, or just white (not a colour used for any of the above). - Even the animated Java logo displayed while the applet is loading flickers. - Pulpcore example applets flicker too in Chrome. They don't start in Safari (thinks Java is not installed!). - The Oracle example applet doesn't flicker, until you add more drawing code, at which point it does. - The LWJGL applet? Works just fine. >_< For reference, this is the code for Test 3: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334
| package prototype.move;
import java.awt.BorderLayout; import java.awt.Color; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.Toolkit; import java.awt.image.BufferedImage; import java.io.BufferedInputStream; import java.io.InputStream; import java.util.ArrayList;
import javax.swing.ImageIcon; import javax.swing.JApplet; import javax.swing.JPanel; import javax.swing.SwingUtilities;
import com.triangularpixels.rebirth.resources.ResourcePool; import com.triangularpixels.rebirth.resources.Resources;
import prototype.move.renderer.Util;
public class MainTest extends JApplet implements Runnable { private final static String dir = "Creatures"; private final static int nimgs = 2; int loopslot = -1; ImageIcon imgs[]; private boolean debug; private CustomPanel panel; private BufferedImage framebuffer, backbuffer; private Thread gameThread; private boolean running = true; private long lastFrameTime; private ArrayList<Long> frameTimes; private ResourcePool resources; private Flow flow; @Override public void init() { super.init(); try { SwingUtilities.invokeAndWait(new Runnable() { public void run() { initialiseInternal(); } }); } catch (Exception e) { e.printStackTrace(); } running = true; gameThread = new Thread(this); gameThread.start(); } @Override public void stop() { super.stop(); if (gameThread != null) { running = false; try { gameThread.wait(); } catch (Exception e) {} } } private void initialiseInternal() { applySleepWorkaround(); panel = new CustomPanel(); panel.setBackground(Color.blue); setContentPane(panel); framebuffer = Util.createImage(320, 180, false); backbuffer = Util.createImage(getWidth(), getHeight(), false); try { debug = false; assert (debug = true); resources = Resources.createPool("Data", Resources.DecoderGroup.CORE, debug, true); resources.parse("resources.xml"); resources.requestCreateAll(); while (!resources.areAllCreated()) { resources.update(); Thread.yield(); } flow = new Flow(resources, framebuffer.getWidth(), framebuffer.getHeight(), panel); } catch(Exception e) { System.err.println("Couldn't create resource pool"); e.printStackTrace(); } frameTimes = new ArrayList<Long>(); imgs = new ImageIcon[nimgs]; for (int i = 0; i < nimgs; i++) { imgs[i] = loadImage(i + 1); } } private synchronized void paintInternal(Graphics g) { if (backbuffer != null) { g.drawImage(backbuffer, 0, 0, null); } } @Override public void run() { while (running) { updateInternal(); drawInternal(); panel.repaint(); sync(60); } } private void updateInternal() { resources.update(); flow.update(isPaused()); } private boolean isPaused() { final boolean hasFocus = this.isFocusOwner() || this.hasFocus(); return !hasFocus; } private synchronized void drawInternal() { if (!isVisible()) return; Graphics2D g = (Graphics2D)backbuffer.getGraphics(); g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON); Graphics2D frameGraphics = framebuffer.createGraphics(); frameGraphics.setColor(Color.black); frameGraphics.fillRect(0, 0, framebuffer.getWidth(), framebuffer.getHeight()); flow.draw(frameGraphics, isPaused()); frameGraphics.dispose(); g.drawImage(framebuffer, 0, 0, panel.getWidth(), panel.getHeight(), null); while (frameTimes.size() > 20) frameTimes.remove(0); if (frameTimes.size() > 1) { long totalDelta = 0; for (int i=0; i<frameTimes.size()-1; i++) { long delta = frameTimes.get(i+1) - frameTimes.get(i); totalDelta += delta; } totalDelta /= (frameTimes.size()-1); int fps = totalDelta > 0 ? (int)(1000 / totalDelta) : 0; int x = 800; int y = 20; String fpsString = fps +" fps"; g.setColor(Color.white); g.drawString(fpsString, x-1, y-1); g.drawString(fpsString, x+1, y-1); g.drawString(fpsString, x-1, y+1); g.drawString(fpsString, x+1, y+1); g.setColor(Color.black); g.drawString(fpsString, x, y); }
g.dispose(); } @Override public synchronized void paint(Graphics g) { super.paint(g); } @Override public synchronized void paintComponents(Graphics g) { super.paintComponents(g); } private static void applySleepWorkaround() { new Thread("SleepTimerHack") { { this.setDaemon(true); this.start(); } public void run() { while(true) { try { Thread.sleep(Integer.MAX_VALUE); } catch(InterruptedException ex) {} } } }; } public void sync(final int framerate) { final int framerateMillis = 1000 / framerate; long current = System.nanoTime() / 1000000; long elapsed = current - lastFrameTime; do { try { Thread.sleep(0); } catch (InterruptedException e) {} current = System.nanoTime() / 1000000; elapsed = current - lastFrameTime; } while (elapsed < framerateMillis); lastFrameTime = current; frameTimes.add(current); } public class CustomPanel extends JPanel { public CustomPanel() { super(new BorderLayout()); } @Override public synchronized void paint(Graphics g) { super.paint(g); } protected synchronized void paintComponent(Graphics g) { super.paintComponent(g); paintInternal(g); } }
protected ImageIcon loadImage(final int imageNum) { String path = dir + "/T" + imageNum + ".png"; final int MAX_IMAGE_SIZE = 1024 * 16; InputStream in = this.getClass().getClassLoader().getResourceAsStream(path); BufferedInputStream imgStream = new BufferedInputStream(in); if (imgStream != null) { byte buf[] = new byte[MAX_IMAGE_SIZE]; int count; try { count = imgStream.read(buf); imgStream.close(); } catch (java.io.IOException ioe) { System.err.println("Couldn't read stream from file: " + path); return null; } if (count <= 0) { System.err.println("Empty file: " + path); return null; } return new ImageIcon(Toolkit.getDefaultToolkit().createImage(buf)); } return null; } } |
Very confused. 
|
|
|
|
theagentd
|
 |
«
Reply #1 - Posted
2011-11-05 00:34:00 » |
|
Chrome, not a flicker in sight.
|
Myomyomyo.
|
|
|
Orangy Tang
|
 |
«
Reply #2 - Posted
2011-11-05 00:40:38 » |
|
Chrome, not a flicker in sight.
On all of them? What Java vm and OS? I'm on 1.6.0_26 and OSX 10.6.8.
|
|
|
|
Games published by our own members! Check 'em out!
|
|
theagentd
|
 |
«
Reply #3 - Posted
2011-11-05 01:03:08 » |
|
Yeah, but the 3rd test only shows a white screen.
|
Myomyomyo.
|
|
|
Cero
|
 |
«
Reply #4 - Posted
2011-11-05 01:25:04 » |
|
Albion and Test 2 work beautifully
Test 3 stays white
Win 7, Opera
Edit: Java Version: 1.7.0_01 21.1-b02 (32-bit)
|
|
|
|
SimonH
|
 |
«
Reply #5 - Posted
2011-11-05 01:53:33 » |
|
Same as Cero - FFox, java 6
|
|
|
|
BoBear2681
|
 |
«
Reply #6 - Posted
2011-11-05 02:17:38 » |
|
OS X 10.5, Firefox, Java 1.6.0_26.
Albion runs smoothly, looks good. The second applet flickers white so much it's unbearable. The third applet is just a white rectangle.
|
|
|
|
|
Riven
|
 |
«
Reply #7 - Posted
2011-11-05 03:20:56 » |
|
Test 3 1 2 3 4 5 6 7 8 9
| network: Connecting http:Couldn't load 'Creatures/Baron_Casual.png' java.lang.NullPointerException at prototype.move.renderer.ImageResource.loadImage(ImageResource.java:42) at prototype.move.renderer.ImageResource.create(ImageResource.java:27) at com.triangularpixels.rebirth.resources.ResourceHandle.create(ResourceHandle.java:88) at com.triangularpixels.rebirth.resources.ResourcePool.processCreateQueue(ResourcePool.java:211) at com.triangularpixels.rebirth.resources.ResourcePool$BgCreator.run(ResourcePool.java:509) at java.lang.Thread.run(Unknown Source) |
|
|
|
|
ra4king
|
 |
«
Reply #8 - Posted
2011-11-05 03:57:29 » |
|
I get the same exception as Riven for Test 3 but Albion and Test 2 work beautifully.
I blame OS X and Apple's new applet changes as the cause of your flickering.
|
|
|
|
jonjava
|
 |
«
Reply #9 - Posted
2011-11-05 06:37:50 » |
|
Albion and Test 2 work beautifully
Test 3 stays white
Win 7, Opera and FFox
Java Version: 1.6.0_27
|
|
|
|
Games published by our own members! Check 'em out!
|
|
JL235
|
 |
«
Reply #10 - Posted
2011-11-05 10:45:45 » |
|
This is a known issue with applets on OSX. Here on the Apple Java Dev mailing list you can see an approximate cause of the issue, that the applet now lives out of the browser process. That mail is talking about it in relation to drag and drop, but it summarizes the problem. Yes, the windows plugin is also NPAPI, but the problem lies in the way the windowing system delivers events and controls access to windowing resources between processes. On Windows, it is perfectly reasonable and possible to have process A own a window/control that is parented in a window created by process B. This is not the case on Mac OS X, Mac OS X will not let process A parent its window in process B's window hierarchy without explicit permission from process B (the host process). Since the host process in this case is the browser, and the only aperture through which we interact with the browser is NPAPI and it does not have a way to tell the browser to execute arbitrary native code in the browser's process space, there are lots of issues that arise from this limitation. On Windows and Linux the Java applet process creates windows and controls inside the browsers window hierarchy, which is just not possible on Mac OS X without browser participation (this is a security feature).
How we manage to show the Applet UI inside the browser is through some cross-process magic that is provided to us by CoreAnimation remote layers, but CA does not remote the events itself. ...
Here is another discussion about it on the Chromium bug list.
|
|
|
|
ava
Junior Newbie
|
 |
«
Reply #11 - Posted
2011-11-05 12:15:01 » |
|
Albion doesn't flicker, but it's unbelievably slow (~4 fps). Test 2 doesn't flicker either, but it runs a lot better than the first one (62 fps). Test 3 stays white.
Ubuntu 10.04 Firefox 7.0.1 Java 1.6.0_26
|
|
|
|
|
loom_weaver
|
 |
«
Reply #12 - Posted
2011-11-05 14:15:22 » |
|
1. Blank black screen 2. Flickers 3. Blank white screen MacBook, Safari running in Snow Leopard. 
|
|
|
|
|
Orangy Tang
|
 |
«
Reply #13 - Posted
2011-11-05 16:48:02 » |
|
So applets on osx suck then. Yey! 
|
|
|
|
theagentd
|
 |
«
Reply #14 - Posted
2011-11-05 16:52:51 » |
|
So? OpenGL on OSX sucks too. There are lots of things that suck on Macs.
|
Myomyomyo.
|
|
|
kappa
|
 |
«
Reply #15 - Posted
2011-11-05 16:57:19 » |
|
- The LWJGL applet? Works just fine. >_<
Just make the switch then and get on with the game  Quite a bit of effort went into finally making LWJGL applets work again on OS X after Apple crippled/broke the Java plugin with the switch to CoreAnimation. The performance on both Java2D and PulpCore is now massively crippled making them unusable for certain types of games. On the other hand OS X has solid support for OpenGL (since the OS uses it) and therefore LWJGL applets are a pretty good option there.
|
|
|
|
|
Orangy Tang
|
 |
«
Reply #16 - Posted
2011-11-05 16:57:23 » |
|
So? OpenGL on OSX sucks too. There are lots of things that suck on Macs.
Lets not turn this into a platform fanboy thread please.
|
|
|
|
loom_weaver
|
 |
«
Reply #17 - Posted
2011-11-05 17:42:38 » |
|
Just trying to be helpful here. If you're creating a game would you like to know if it can run on Macs? Or would you rather that I say nothing?
|
|
|
|
|
Cero
|
 |
«
Reply #18 - Posted
2011-11-05 17:47:38 » |
|
Just trying to be helpful here. If you're creating a game would you like to know if it can run on Macs? Or would you rather that I say nothing?
his reply to you was sarcastic and disappointed, that it doesnt work on mac - not critical
|
|
|
|
loom_weaver
|
 |
«
Reply #19 - Posted
2011-11-05 17:51:29 » |
|
Just trying to be helpful here. If you're creating a game would you like to know if it can run on Macs? Or would you rather that I say nothing?
his reply to you was sarcastic and disappointed, that it doesnt work on mac - not critical Nod, I kind of figured that after I saw the second post. My question is aimed more at the general audience. I've noticed a slight trend of "don't bother me about the problems running your platform (which is different from mine)" attitude.
|
|
|
|
|
h3ckboy
|
 |
«
Reply #20 - Posted
2011-11-05 17:53:59 » |
|
I think it is just sort of a killing the messenger kind of thing, and being frustrated at the problem and maybe leaking some of that frustration into the conversation.
|
|
|
|
|
ra4king
|
 |
«
Reply #21 - Posted
2011-11-05 18:03:57 » |
|
In the end, Apple is slowly killing Java applets 
|
|
|
|
Orangy Tang
|
 |
«
Reply #22 - Posted
2011-11-05 19:23:19 » |
|
Just trying to be helpful here. If you're creating a game would you like to know if it can run on Macs? Or would you rather that I say nothing?
Sorry didn't mean to imply your response was unwanted. I'm just pretty miffed at how hard it seems to be to get a consistant experience across platforms. Especially since your setup appears to be near identical to mine.
|
|
|
|
JL235
|
 |
«
Reply #23 - Posted
2011-11-05 19:46:48 » |
|
Just trying to be helpful here. If you're creating a game would you like to know if it can run on Macs? Or would you rather that I say nothing?
Sorry didn't mean to imply your response was unwanted. I'm just pretty miffed at how hard it seems to be to get a consistant experience across platforms. Especially since your setup appears to be near identical to mine. Welcome to Java!
|
|
|
|
Mads
|
 |
«
Reply #24 - Posted
2011-11-06 03:27:48 » |
|
Yeah, but the 3rd test only shows a white screen.
Same exact result. Chrome, win7. (build 1.6.0_26-b03)
|
|
|
|
theagentd
|
 |
«
Reply #25 - Posted
2011-11-06 03:37:49 » |
|
I didn't mean to insult anyone who favors Macs (AKA "I'll buy anything that's shiny and made by Apple!" xDDDDD), but game support on Macs has always been pretty bad in my experience. Considering the really old version of OpenGL supported by Macs along with the bugs I hear about all the time, it just isn't worth my time to look into it as a person interested in graphics programming. I am in no way fanboying Windows here, I'm just saying that at least I can haz tessellation, texture arrays and samplers and multisampling coverage masks in my shaders there.
|
Myomyomyo.
|
|
|
ra4king
|
 |
«
Reply #26 - Posted
2011-11-06 04:52:38 » |
|
I am in no way fanboying Windows here, I'm just saying that at least I can haz tessellation, texture arrays and samplers and multisampling coverage masks in my shaders there.
Well that is if the user is running a decent graphics card with decent OpenGL support too 
|
|
|
|
JL235
|
 |
«
Reply #27 - Posted
2011-11-06 15:55:34 » |
|
I am in no way fanboying Windows here, I'm just saying that at least I can haz tessellation, texture arrays and samplers and multisampling coverage masks in my shaders there.
Well that is if the user is running a decent graphics card with decent OpenGL support too  NVidia drivers are (mostly) excellent these days, and can even ignore/workaround OpenGL bugs in your code. The Intel chipsets and drivers are also no where near as bad as they used to be.
|
|
|
|
theagentd
|
 |
«
Reply #28 - Posted
2011-11-06 17:36:25 » |
|
I am in no way fanboying Windows here, I'm just saying that at least I can haz tessellation, texture arrays and samplers and multisampling coverage masks in my shaders there.
Well that is if the user is running a decent graphics card with decent OpenGL support too  NVidia drivers are (mostly) excellent these days, and can even ignore/workaround OpenGL bugs in your code. The Intel chipsets and drivers are also no where near as bad as they used to be. My experience with Radeon is limited to the antique Radeon card in my family's old computer. It had FBO support, but it apparently couldn't handle colors in them. I have no idea what the hell was going on, and I never even bothered to investigate such a ridiculous bug. xD Nah, I haven't found any really serious bugs yet in any drivers today. Granted I've been ignoring Intel, but Radeon and NVidia is fine. I do have a few bugs concerning antialiasing though. Reading sample positions when using driver forced antialiasing will give you some very interesting positions. Multisampled HDR FBO rendering is limited to 4xMSAA Retested it, and it's fixed in the latest drivers. For some reason, the driver reports that "16xMSAA" is available, but when you use it it gives you 2x2 OGSSAA + 4xMSAA. "32xMSAA" is also available, being 2x2 OGSSAA + 8xMSAA. Coverage sampling also works. The funny thing is that this is only with FBOs. There are some bugs with getting antialiasing on the main screen buffer (Display.create()). The only coverage sample mode supported is 32xCSAA (based on 8xMSAA). Everything under that just gives the number of coverage samples requested as color samples, e.g. if I say 4 color, 16 coverage (=16xQ) I get 16xMSAA (see above). It works if I force it through my drivers though. Could be either the OpenGL driver or LWJGL. The .withCoverageSamples() methods seem very unreliable.
|
Myomyomyo.
|
|
|
gbeebe
|
 |
«
Reply #29 - Posted
2011-11-06 17:58:20 » |
|
I have found that if I'm using an image as a buffer, adding 1
| setIgnoreRepaint(true); |
to init() stops people complaining about flickering (and freezing) when I don't even experience it on my machine.
|
|
|
|
|
|