i try to implement 3D picking in an android app. I use OpenGL ES2.0.
Now I want to read the depth buffer (which is written in an FBO) but glReadPixels returns only 0.
The code is correct, because I tried the same code after calling my RenderInTexture function and it returns the correct values.
Calling RenderInTexture in the OnPick function and than call glReadPixels returns also 0.
What is the problem?
Isn't it possible to read a framebuffer in the OnPick event or do i have to set some variables?
Thanks for help.
Is the OnPick called on the main (UI) thread? Probably you have two threads, the opengl rendering thread and the main application thread where events are sent. Try storing the onpick coordinates in you OnPick method and do the computation in the opengl thread.
Hope that helps.
Related
I have two threads running in my program. When I try to use OpenGL functions in the thread that is not my main, it throws an IllegalStateException:No OpenGL context is current in the current thread. So my question is, how do I pass the context from the main thread to a different thread? I am using LWJGL 3.
I think I solved it but I'm not 100% sure it's the best way to do it. You have to call GLFW.glfwMakeContextCurrent(MemoryUtil.NULL); in the thread you want to depart from, then call GLFW.glfwMakeContextCurrent(window); GLContext.createFromCurrent(); from the thread you want to switch to.
Take a look at this example. It uses a Drawable that you can use in your two Java Threads. I'm not entirely sure if it still works since a lot of this class is associated with LWJGL 2. I'll test it soon and let you know if this or your method is more efficient (Gonna create a tiny micro-benchmark :) .
I added a breakpoint in my onDraw() method and noticed that my debugger only gets there after the method in which invalidate(rect) is, ends. Is it possible to be called right after?
Because I need to call invalidate(rect) twice in my method.
Thanks in advance.
No. Calling invalidate() is a signal to the framework that a portion of the screen is dirty and needs to be redrawn. The actual drawing doesn't happen immediately... it happens the next time through the main thread's event queue.
I have faced such problem with me and as alex saying it'll not happen. I can suggest one workaround that u can have your own implementation of onDraw() method with different name like myOnDraw() only when it should be not very heavy. so instead calling or depending upon onDraw() to be called immediately u can call that method which will work for u when u need it.
I'm currently working on a multi-threading safe rendering system and I would like to know your thoughts on how to correctly update the next step in the game world while the previous scene is currently rendering. Currently I am using LWJGL Opengl Bindings with Java. Here is pseudocode for my game loop as it is currently set up (which is probably just a basic loop that most people are familiar with):
//DrawingLayers are wrappers for in game entities and has an update
//and render method
game-loop:
addInputEventsToInputStack()
removeCompletedDrawingLayers()
foreach layer in DrawingLayerQueue :
layer.update(deltaTime) //update position/color/size for entity
layer.render() //performs OpenGL calls
if(layer.isCompleted):
addToCompletedDrawingLayersList()
swapBuffers() //blocks until scene is fully rendered
goto game-loop
My problem lies in the swapBuffers() method as it blocks until the scene is rendered which means I cannot perform any updates while that is going on. My thought on how to get around this is to:
Have a copy of all DrawingLayers that I use for updating the state of the entities and have the other copy as a reference for the rendering thread. And while a frame is rendering, kick off a thread just before swapBuffers() to update the copy that is not in use.
I'm wary of this approach as I believe creating the copies before every frame would slow the system down more than I would like.
Does my approach make sense, and if not, do you guys have any recommendations for how to do this? I'm open to a complete restructuring.
Updated: Based on datenwolf's suggestion I've changed my gameloop to the following:
//DrawingLayers are wrappers for in game entities and has an update
//and render method
//A future for the pre-processing task
Future preProcess = null
game-loop:
//Update: checks if we have a preprocessed update to wait for
//and waits for it to complete
if(preProcess != null):
preProcess.get()
preProcess = null
addInputEventsToInputStack()
removeCompletedDrawingLayers()
foreach layer in DrawingLayerQueue :
layer.render() //performs OpenGL calls
if(layer.isCompleted):
addToCompletedDrawingLayersList()
//UPDATE: the following just calls all the update methods for the layers
// in a new thread
preProcess = executorService.submit(new UpdateRunnable())
swapBuffers() //blocks until scene is fully rendered
goto game-loop
So far with this I've got a significant improvement in performance. There may be some race condition issues that I cant see, but overall Im happy with this improvement.
in the swapBuffers() method as it blocks until the scene is rendered
The blocking of the buffer swap is only partial by finishing the rendering. It usually also blocks due to wait for the retrace. However OpenGL guarantees you, that after any drawing command returns, the buffers accessed by it can be safely modified without any pending rendering operations being impaired. The implementation is required to make copies or copy-on-write mappings to all data.
Or in short terms: Just modify the data in the buffers. As soon as drawing calls (glDrawArrays, glDrawElements) return it's safe to do so.
I have a java application that streams raw data and draws real time plots accordingly. this is handled by calling methods from a class i wrote that uses the Graphics object. i implemented algorithms in an overridden paintComponent method to generate all the plots from the most recent data. i have other methods in my class to update variables used in the paintComponent method to draw the graphs.
in my main class, i update my graphs periodically in a timer event handler. in the event handler i call methods from my graphs class that update certain variables, do a few calculations, and then call repaint() (which apparently is the correct way to call the paintComponent method).
my problem is, the algorithms i use in the paintComponent method can take a (relatively) long time to complete depending on the amount and resolution of my plots. (i haven't exactly run into this problem yet, but i'm trying to address it now). of course i wouldn't want all this graphing to hog all the processing time of my application, so i was wondering if it's possible to have "paintComponent" execute in a separate thread.
what would happen if i created a subclass in my main to run in a separate thread and simply called the graph methods i described? would that automatically make all of those methods (including paintComponent) execute in the new thread? or would i have to modify my graph class itself for this to work? ideally i would like to avoid modifying my graphs class because i have already designed it to work within the NetBeans GUI builder as a JPanel, and i'd like to avoid breaking that functionality.
There's a couple options.
One method is to use two BufferedImages, where you draw on one in separate thread, and paint from the other one, and switch as drawing completes (for what I assume is a snapshot every so often.)
A much better solution is to have a model of directly renderable data (as in the data it holds can be drawn without performing any further algorithmic work on it).
This means you will perform your alogirthms on a separate thread, calculate the values that will be used to paint, call SwingUtilities.invokeLater to update the model. The model will then only get updated on the Swing thread, and when you repaint, you have access to exactly the data you need to draw (and no extraneous data).
If this data is still so much that painting takes a long time (ie: if you're drawing charts with tons of data points), you'll send to calculate which parts of your window need repainting and fire repaint() on just that. This piece should be a lat resort however. 99% of your performance will come from moving the algorithms into a separate thread, and giving the painter access to directly renderable data.
If you look at best practices on updating a TableModel with external data, what you have is the work that gets the data occurring in a background thread (typically SwingWorker) and then posted to the actual model via invokeLater() (This is so the data doesn't get modified while your paint() is trying to read it.) and then firing appropriate events from within the model update that tell the table what cells changed. The table then knows what part of its viewport needs repainting and fires the appropriate repaint() method. During this time the background thread can continue retrieving data and adding new updates to the event queue via invokeLater.
you have to redirect paint methods to the SwingWorker or Runnable#Thread (all output to the GUI must be wrapped into invokeLater), example here or here
Well, if you want to improve the responsiveness of the GUI you could do the lengthy work in a SwingWorker, although I don't know that doing so will speed up your application any more.
I have a java application that streams raw data and draws real time
plots accordingly. this is handled by calling methods from a class i
wrote that uses the Graphics object.
To complete other's answer:
you should really consider to use JFreeChart. It's a good library for drawing charts and you can modify dynamically the displayed dataset (and do a lot of more things).
I NEED to preload some textures in the non-main-thread of an OpenGLES application. I read this: Can't call glGenTextures on multithreaded android app but its more the Java version of what I need. How do I tell my loading Thread to upload/create a texture into the main loop? I read something about creating a context and share with the main context somehow. How?
There are two steps to get textures from resources/disk to rendering in GL, and they can be separated to allow most of the loading and computational work on a worker thread.
The first step is the actual creation of a Bitmap at the Java level, which will use something like BitmapFactory.decodeResouce(). This part can be done on any thread you like, and when you're done loading you throw that bitmap into an ArrayList or queue or whatever. Make sure you surround the access of the list with a synchronized block.
The second step is to call glGenTextures, which has to be done in the GL thread. So at the beginning of your drawFrame() method, check the size of that ArrayList you're saving bitmaps to, and if the size is bigger than 0, make some calls to glGenTexures and remove and recycyle the bitmaps from the array.