I want to capture the screen. Libgdx provides some functions defined in the ScreenUtils class.
For instance final Pixmap pixmap = ScreenUtils.getFrameBufferPixmap(x, y, w, h);
My problem is that it takes about 1-3 seconds to get that information. During that time the game loop is blocked and the user will define it as a lag.
Internally the ScreenUtils class, uses Gdx.gl.glReadPixels. If I run the ScreenUtils.getFrameBufferPixmap method in a thread, there is no lag, but it captures the screen at the wrong method, which is logical since the game loop runs and changes stuff.
Is it somehow possible to copy the GL context or save it and generate the Pixmap at a later point of time with the help of a Thread? Of course the copy/save operation should be done instantly, otherwise I don't spare anything.
I use ShapeRenderer to render my stuff onto the screen.
After little research I have found faster alternative to glReadPixels - Pixel Buffer Object which is available since Android 4.3 - https://vec.io/posts/faster-alternatives-to-glreadpixels-and-glteximage2d-in-opengl-es
It is not possible to call glReadPixels on other thread than render thread - https://stackoverflow.com/a/19975386/2158970
I have found a solution, which works in my case since I have only minor graphics / shapes. Basically I copy all the objects, which are drawn to the view, as described here. In a background thread I generate a Bitmap programmatically and use the information stored in my objects to draw to the bitmap.
Related
I am writing a Java 2D video game. I am using only the Java 2D api, and all updates are driven off a single update timer. I perform all the drawing in a JPanel utilizing paintComponent(), and I use Volatile Images for all of the graphics images from what I have read should be a performance increase.
In spite of all this, at times my video game starts flickering like crazy. The whole screen starts flashing. The game is written in Java 6, and I am running on Mac OS X 10.10.1.
Any ideas on how to fix this?
Thanks.
According this post you shouldn't call paintComponent() directly. Try calling paint() instead.
Edit: Sorry, I confused paintComponent() and paintComponents(). Maybe you could show some code?
Call setDoubleBuffered(true) on your main window/frame/panel. Or draw to another component and switch when ready.
The flickering occurs because you quickly redraw on the same component. Redrawing in the background, and then quickly switch to the now newly drawn picture gets rid of this. This is called double buffering. Read more here.
I'm using the Slick2D Java game library and I want to set the scale of the graphics object that gets passed to the render method in my game loop. I'd like to do this outside the render method, so that I would only have to call the setScale() method once. I am implementing my game as StateBasedGame, so I'd to like to initialize my graphics object in my StateBasedGame class. Where would be the appropriate place to do this?
In the Init method, where you should be initializing your image. I can expand upon this, but your question seems to acknowledge that you already know how to scale the image.
EDIT: After rereading the question, the answer would be that you need to scale it every time you go into the render method of your gamestate object. This requires that you put graphics.scale(0.5f, 0.5f);
This is required, I believe, because the graphics object resets its scale every game tick so that you don't get a compounded effect as it calls the render method hundreds of times.
I am conducting a learning experiment with Java. I am attempting to create a simple "Megaman" style game using Java and the 3rd party API "LibGDX". I have obtained a rather solid understanding of the relationship between the OrthographicCamera object from LibGDX and the World object from LibGDX's implementation of "JBox2d".
However, when I resize the window the objects inside World stretch. I have made use of the resize(int width, int height) method of the Screen interface. Inside of which i reset the OrthographicCamera's width and height. This does not seem to have any effect of the way the images looks or behaves in the physics simulation.
So my question is this: How do i properly resize a LibGDX/JBox2d application's window without distorting the objects being simulated?
here is the code (in the form of a git repo because i find GitHub faster, easier, and kinder to the SO server...)
EXTERNAL LINK
https://gist.github.com/konnerdroid/8113302
EXTERNAL LINK
AHA!!!! i wasnt updating my camera...
For any changes made to the camera to be visible and their effect to be felt you need to call camera.update() either in your loop or after any changes are made
well... at least i learned how to use github =)
I have a custom UI drawn for my java application. Right now I draw the entire UI from scratch. I know for a fact some parts of the UI are static. I know I could save these static parts to an image, but will this yield a improvement in performance (Since even an image must be drawn every frame)?
Is it plausible to save a reference to the Graphics2D object after the UI has been drawn and assign that to the new graphics object every frame (starting from a point where all the static components are drawn)?
Thanks in advance,
Alan
You don't need to redraw everything in every frame. So if you have static parts of your UI (or even dynamic parts that you know haven't changed since last frame) then you simply don't need to repaint them.
In my code (Swing games and simulations mostly) I usually try to follow the following rules:
Pre-prepare static images (e.g. BufferedImage textures for UI elements)
Override the paintComponent() method for each UI element individually to do the painting
Only call the repaint() method of any given UI element if I know that something has changed
Call repaint() in a timer-based loop for animation, but only call it on the portion of the UI that is being animated (e.g. a nested JPanel)
This approach seems to work and perform pretty well (though I'd welcome comments if there are ways to improve it!!)
There are two main optimizations you can do here. The first is to make sure that when you cause your UI to be repainted, usually done by calling repaint, make sure you call the version of repaint where you specify a rectangle that has changed. Only make the rectangle big enough to encompass the parts that actually have changed, not the static parts. For this to be effective you also have to pay attention to the clipRect in the Graphics2D object you are passed in paint(). That is used by the system to tell you exactly what needs to be repainted, in the above case usually the rectangle that you passed to repaint. Don't paint anything that lies entirely outside that rectangle.
You can also get significant performance improvements by caching the static parts of your interface in an image. Writing an image is by far the fastest way of getting things onto a screen. My measurements indicate that small images are faster than even a few simple drawing primitives. However you need to make sure the image characteristics match the screen, by using createCompatibleImage().
Of course you may be using a lot of memory to get this speedup. I would recommend testing to see if you need to do image caching before implementing it.
if some parts of the screen is completely static, then never redraw that part. Don't do a full-screen/window clear, just clear the part of the screen/window that changes all the time.
This way, you don't unnecessarily redraw the static image.
I'm developing a fair sized hospital simulation game in java.
Right now, my pain method is starting to look a little big, and I need a way to split it up into different sections...
I have an idea, but I'm not sure if this is the best way.
It starts by painting the grass, then the hospital building, then any buildings, then people, then any building previews when building. The grass and hospital building will not change, so I only need to paint this once. The buildings themselves won't change very often, only when new ones are built.
I was thinking, use boolean values to determine which sections need repainting?
Ideal, id like to be able to split up the paint method, and then call each one when needed, but I'm unsure how to physically split it up.
I am still quite new to java, and learning on the go.
Thanks in advance.
Rel
Another idea is to create a super class or interface for all items that must be drawn on the screen. Lets cvall this class ScreenObject. You can then have a draw(Graphics2d g) method specified in the ScreenObject class. Next, each object that must be drawn implements the draw() method and is only concerned about drawing itself. You can even consider creating a variable that determines whether this draw method should be run at all.
In the main class that paints the screen you can have a reference to all ScreenObjects in an ArrayList and your paint() method will simply iterate over this calling draw() on each object.
I'm assuming from your description that your scene is split up into tiles. Keeping an array of booleans is a good way to keep track of which tiles need redrawn on the next update. A LinkedList might perform a little better in some situations. (I'm thinking of a Game of Life simulation where there are tons of tiles to redraw and you need to check each neighbor, so you may not need to go this route.)
Without seeing your code I can't give very specific advice on splitting up your paint method. I can tell you that in sprite animations, each sprite object typically has its own draw method that takes the main Graphics object (or more likely a buffer) as a parameter. Since the sprite should know its own image and location, it can then draw itself into the main image. Your paint method can then just loop through your list of sprites that need to be redrawn and call their draw method.
You might look to Killer Game Programming in Java for more detailed information.
Well I am not really an expert at programming but to split up my paint method Ive always just made a new method that takes a Graphics object and call that from paint, it has always helped me to keep my code organized but I have never had a big project like it sounds you are working on so it might not work for your situation.