I'm writing a game in Java, LJGWL (OpenGL). I'm using a library that handles a lot of messy details for me, but need to find a lot faster way to do this.
Basically I want to set every pixel on the screen to say a random color as fast a possible. The "random colors" is just an Array [][] that gets updated every 2-3 seconds. I've tried drawing rects and using images, both are pretty slow for what I want to do.
I think I want to learn how to write a GPU shader? That is the fastest way to do this? LJGWL exposes OpenGL api to java. Any basic tutorials on how to get started with OpenGL shaders? Or should I dynamically create a texture of some sort and then just throw up the entire texture, would that be faster?
If it were the case that you were statically displaying the same image, than using a texture or display list would suffice. But as you want to frequently update it, shaders really are the best option. Shader code executes on the GPU and modifies data in GRAM, so you have no bottle neck transferring from CPU to GPU. The next best thing would probably be a Pixel or Frame Buffer Object. Buffer Objects let you read/write to GRAM via DMA (without having to go through the CPU) so they can be pretty fast.
I haven't written any shaders yet, so I can't recommend any good resources. But SongHo's OpenGL pages are a good place to learn about Buffer Objects. (His examples are in C++ though)
Textures are the fastest way to draw something on screen, draw a texture mapped quad into the screen, it should be fast enough. When you need to reupload the texture data, use glTexSubimage2D to update it.
No need to use shaders.
I've yet to do any work with shaders in OpenGL, but given the same scenario in multiple occasions, I handled it with a texture I threw up across the screen on top, and it worked quite effectively.
I don't know how you are drawing your pixels exactly, but this limit you hit could be because of the amount of data you transfer (inefficiently?). Updating a screen full of pixels every 2-3 seconds shouldn't be hard at all. Although shaders bring you closer to the graphics card, they will never make inefficient methods fast, so...
Why is your code so slow?
What code? What code exactly did you try? What texture did you use, render to, ...?
Is it slow? How slow? How fast do you expect it to be?
How quickly can one get 1920x1080(?) pixels in video ram, what's your hardware, drivers, OS?
I think you need to edit/repost before we can help you solve your problem. Just because it is slow, is no guarantee at all that shaders will even be one bit faster.
Related
I am trying to make a game where you have multiple levels where you have to figure out a way to where a certain color should go through pipes that are displayed on the screen. The pipes look like (it all should be better, but just as a reference). So basically there should be an animation of color going down these pipes (different color for different pipe). Now, I can make a gif and use that as my animation, but it's just too large (aprox. 5MB, which isn't a lot, but if you put dozens of levels, it tends to add up).What would be a solution that would be the most efficient?
Well I would first recommend you to go with Unity for Game Development.
If not then check out cocos2d or any other frameworks.
Secondly, if you want to animate things using the native code, then play around with draw() functions (as suggested by #Wakeman) of the Canvas.
Now coming to your question, if your game does not involve continuous user interaction and you are thinking of GIFs as a solution then I would recommend using Lottie library.
You can create beautiful animations in Adobe After Effects and import those (json files) in Android without hurting much memory, plus would get high resolution output.
Have you tried using the drawRect() or drawCircle()? You only need coordinations of the starting point, the turning points, and the ending point. Draw it with a recursive function with delay, and it should look good.
It would be better to construct your levels as tilemap. Every segment of pipe can be coded by number and drawn as bitmap (Sprite) that depends on its state (empty, 1/4, 1/3, 1/2 or full). Similar principles works for engines like Unity/Cocos 2D or your own renderer. This way of building your levels would be hundred times lighter in size than full screen animation and used multiple times for different levels.
For my work I had to get into OpenGL 3d rendering recently, and I admit I'm quite new to this topic.
Without getting into too much detail, I have to deal with a HUGE array of data (vertices) from which I need to draw a shape. Basically, think of a plane of a very odd shape in 3d space. This shape is being added to on the fly. Think of a car moving on a plane and painting it's trail behind it - but not just a simple trail, but with holes, discarded sections, etc. And it generates a new section several times per second for hours.
So, obviously, what you end up with is A LOT of vertices, that do get optimized somewhat, but not enough. Millions of them.
And obviously I can't just feed it to a GPU of embedded system as a vertex VBO.
So I've been reading about culling and clipping, and as far as I understand I only need to display the visible triangles of this array, and not render everything else.
Now, how do I do that properly?
The simplest brute-force solution would be to go through all triangles, and if they lie outside of frustum - just not draw them. Generate a buffer of what I DO draw and pass it to GPU
One idea I had is to divide world space into squares, a kind of chunks, and basically split the "trail" mesh between them. So each square will hold data for it's part of the trail, and then I could use frustum culling, maybe, to decide which squares to render and which to skip.
But I'm not convinced it's a great solution. I also read that you should reduce the number of GL function calls as much as possible, and calling it for hundreds of squares doesn't seem great.
So I decided to ask for advice among people who would understand the subject better then me. Sadly, I don't get much learning time - I need to dive right into it.
If anyone could give me some directed tips it'd be appreciated.
You'd be better off using some form of spatial partitioning tree (e.g. OctTree, QuadTree, etc). That's a similar approach to your second suggestion, however because it's hierarchical, searching the tree is O(logN) vs O(n).
Alright, I couldn't find a good name for this, so I will explain in a bit further detail.
I am making a game using LWJGL and I have gotten some basic rendering done, but now I want to do something a bit more advanced.
Here is the situation:
I have a mesh (positions, normals, texture coords, indices) I generate which can currently support 1 texture, this would be great if I had a single image containing all of the textures, but sadly that isn't the case. I have a individual image for each texture which needs to be loaded individually.
Now, I see a way how I could do this, but it doesn't seem practical or like a good usage of memory.
-Load all the textures into one image and save where each one is in that image for usage with the texture coords.
The textures should NOT blend together, hard coding anything is not an option as I wish to allow modding to be easy to implement, and anywhere from 1 (best case scenario) to 65,536+ textures (worst case scenario) are able to be used in the same "mesh".
I am simply going to use a Texture Atlas as doing anything else seems impractical. Thanks #httpdigest for the suggestion.
I'm making a 2D game in Java and one of the main issues causing low FPS (on my slow laptop) is having to re-draw complex structures to a Graphics instance, such as dials with markings.
The dial and its markings will never change unless the window is resized, so I thought it would be a good idea to draw to a BufferedImage and just re-draw the image rather than re-drawing the details. The position of the needle obviously changes, so this can just be drawn on top.
I've never heard about this being done to improve the FPS of 2D games so I'm wondering if it's actually good practice to store a cache of images or if there's a better way to solve this sort of problem? Are there any issues associated with this that I haven't considered?
Caching images isn't a bad idea: you can rely on raster rendering to be pretty well optimised on most any platform. In my experience (which is admittedly mostly on mobile devices where 2D graphics are concerned) the Graphics.drawXXX() methods are often considerably slower than Graphics.drawImage().
In my experience the vast majority of 2D games out there make use of sprites (i.e. images) for rendering just about everything. Often that's true even when the graphics look like they are rendered using primitives!
Another useful technique to think about is not redrawing regions at all unless you really need to!
EDIT:
As others have mentioned, the major tradeoff is that you're going to be using more memory. You're also going to have to make sure you free up those images once you no longer need them.
Is it good practice to cache parts of a 2D drawing?
You're making a trade-off between drawing speed and storage space. Only you can determine which is more important.
You might consider rendering your dials in advance and saving the images as GIF, JPG, or PNG files. You would have to scale these images to your window size before you draw them.
Are you using double buffering for your Graphics panel?
Yes, that is a good practice, and it's done all the time. Drawing to an image first before displaying it on the screen is called double buffering, and that method can be used in different ways according to the needs of the program.
The downside of double buffering is memory, since it takes more memory to store the second image, but that sounds like a trade-off you'll need to make.
I want to be able to draw consecutive bitmaps (of type BufferedImage.TYPE_INT_RGB) of a video as quickly as possible in java. I want to know the best method in doing so. Does anyone have any advice where I should start? From what I've read, 2 options are:
1) Use GDI/GDI+ routines in a JNI dll working with JAWT (Im on Windows)
2) Use Java3D and apply Textures to a Box's face and rotate it to the camera
Im interesting in any advice on these topics as well as any others.
I have done a decent amount of GDI/GDI+ programming in VB when i created an ActiveX control, so using GDI should be painless, but im guessing Java3D will utilize the GPU more (I could be wrong) and give better performance. What do you think? GDI and JAWT with my previous experience, or start and new API journey with Java3D.
Thanks in advance. :)
To obtain a fluid animation (if it what you want to get), you need to use double buffering. For doing this, you will need to create a new java.awt.Image (or a subclass like BufferedImage, or if you want OpenGL accelerated processing, VolatileImage) for each frame you want to display. If you haven't already done so, call Image.getGraphics() to get a java.awt.Graphics object (can also be useful to add your content to the Image). At the end, when you hidden Image is complete, call Graphics.draw() to replace the current display smoothly.
VolatileImage is OpenGL accelerated and much faster. When VolatileImage.getGraphics() is called, it actually returns a Graphics2D, which is also part of the accelerated graphic pipeline.
It works on Windows, Linux and Solaris, but you need to have OpenGL drivers installed for your graphic card.
Some additional refs:
Accelerated graphic pipeline:
http://download.oracle.com/javase/1.5.0/docs/guide/2d/new_features.html
http://www.javalobby.org/forums/thread.jspa?threadID=16840&tstart=0
Double buffering:
http://www.java2s.com/Code/Java/2D-Graphics-GUI/Smoothmoveusingdoublebuffer.htm
http://www.heatonresearch.com/articles/23/page2.html
http://www.javacooperation.gmxhome.de/BildschirmflackernEng.html