Strange BufferStrategy issue - Game runs fast only on Intel GPUs

后端 未结 3 1905
迷失自我
迷失自我 2021-02-05 04:10

I ran into a very strange problem, I tried searching for an answer for days and days. My game just got a new particle system, but was too slow to be playable. Unfortunately, Buf

相关标签:
3条回答
  • 2021-02-05 04:49

    When you send things to the GPU, the GPU reads the info from the GDRAM. If you read the data into the memory by calling getDrawGraphics then the memory is probably read from graphics card back into the RAM. The CPU can only access the RAM (DRAM), GPUs can only access the GDRAM. With on-board GPUs this is however different, since they don't come with their own RAM, they use a part of the regular RAM.

    To return cause your code to run quickly, determine which hardware you have, then accordingly call the appropriate method (the one before your code change or the one after).

    0 讨论(0)
  • 2021-02-05 04:51

    Check the size of the pictures compared to the caches, and try to diagnose the number of cache misses. Read up on data oriented design, it's usually a part of that.

    An alternative is to change the way you do the explosions to a way where you don't load in 200 sprites and spread them out (do you reuse them, or do you load them every time you do an explosion?). Making an animated explosion takes less power, though it might not be as spectacular, and you would need to do some animating then.

    Java also isn't the most optimal language for making games. You're working very high level, and the JVM slows things down a bit. My friends had similar problems when making small games, it was difficult to make a game that didn't lag tons.

    0 讨论(0)
  • 2021-02-05 04:53

    Here's a few things to check:


    Without knowing the console/error output of your setBuffers function it's difficult to tell. Is Intel using createBufferStrategy(2); while NV uses createBufferStrategy(3); ? if so that could be part of the issue with it using extra memory.


    Have you tried the java2d System.properties yet? http://docs.oracle.com/javase/1.5.0/docs/guide/2d/flags.html Especially the trace property for debugging.

    Windows only

    System.setProperty("sun.java2d.transaccel", "True");
    System.setProperty("sun.java2d.d3d", "True");
    System.setProperty("sun.java2d.ddforcevram", "True");
    

    All platforms

    System.setProperty("sun.java2d.opengl", "True");
    

    For debugging

    System.setProperty("sun.java2d.trace", "timestamp,log,count");
    //// -Dsun.java2d.trace=[log[,timestamp]],[count],[out:<filename>],[help],[verbose]
    

    Toolkit.getDefaultToolkit().sync(); doesn't actually force monitor VSync, that's done by BufferCapabilities (in your setBuffers function).

        BufferStrategy bf = getBufferStrategy();
        if (bf != null) {
            BufferCapabilities caps = bf.getCapabilities();
            try {
                Class ebcClass = Class.forName(
                    "sun.java2d.pipe.hw.ExtendedBufferCapabilities");
                Class vstClass = Class.forName(
                    "sun.java2d.pipe.hw.ExtendedBufferCapabilities$VSyncType");
    
                Constructor ebcConstructor = ebcClass.getConstructor(
                    new Class[] { BufferCapabilities.class, vstClass });
                Object vSyncType = vstClass.getField("VSYNC_ON").get(null);
    
                BufferCapabilities newCaps = (BufferCapabilities)ebcConstructor.newInstance(
                    new Object[] { caps, vSyncType });
    
                createBufferStrategy(2, newCaps);
    
                // TODO: if success, setCanChangeRefreshRate(false) and setRefreshRate(60). 
                // Possibly override refreshRateSync()?
            }
            catch (Throwable t) {
                // Ignore
                t.printStackTrace();
            }
        }
    

    EDIT this code was from (http://pulpcore.googlecode.com/hg-history/3c4001969922b93048e0a166395115df059a2059/src/pulpcore/platform/applet/BufferStrategySurface.java)

    Also, you should be calling setBuffers AFTER the Canvas constructor has run and it's been added to the JFrame.


    I'm "relatively sure" you don't need to call super.paint(g); I don't know if its what's causing your specific issue, but you should remove the line from your paint function.


    Though you don't show the code, your explosion mechanism using 200 randomly moving sprites could be a major cause for errors. Figure out the maximum number of explosions you want to have on the screen at one time and generate those sprites N * 200 before hand, put them in an array list ArrayList(N) and then in your code reference them cyclically. ExplosionClass = explosionList.get(currentExplosionIndex % explosionList.size());

    0 讨论(0)
提交回复
热议问题