Android: OpenGL: glGenTextures not working in constructor? - java

Can anyone tell me why glGenTextures() isn't working in my constructor?
Here is how my project is setup:
A custom renderer is used which calls .draw on the current active stage.
When a stage is created it assigns itself (the end line of its constructor) to the static Global.activeStage.
Now the renderer calls .draw on the currently active stage which reference is kept inside Global.activeStage.
In the stage I have a function which loads all textures that are needed in the stage.
If I call this function the first time .draw is called there is no problem.
If I call it in the constructor though, everything works except glGenTextures() - it creates a zero value rather than 1..2..3 and so on.
In both cases a global GL10 reference is used rather than the one .draw gets, so it's not the problem.
It seems as if everything works ONLY if there is already a reference to the current stage I'm using (if the stage is created e.g. the constructor has already run).
I am not sure if it is related, but the stage is created in a Thread after onCreateSurface ends.
I could post some of the code if you say which parts would be relevant.

I am quite sure you have to run all openGL operations on the Thread associated with openGL. This is why it works when called from your draw() method called from the renderer (which runs on the GL-Thread) but not from the constructor (which runs on another Thread as you say).

Related

How to call JAWT_FreeDrawingSurface from another thread?

I have an application using Swing and LWJGL running nice and stable using a dedicated rendering thread. I have made sure all OpenGL and JAWT calls are made on my rendering thread and not on EDT (this includes JAWT_GetDrawingSurface, JAWT_DrawingSurface_Lock, JAWT_DrawingSurface_Unlock).
My threads are Java threads, JAWT_xxxx functions are called from the org.lwjgl.opengl.awt toolkit, I have currently no native code of my own.
There is one call left which is done from the AWT thread when the UI components arfe disposed: JAWT_FreeDrawingSurface called from org.lwjgl.opengl.awt.PlatformWin32GLCanvas#dispose. One solution would be to create a customized version of all org.lwjgl.opengl.awt classes and prevent this call being made (and call it from my thread instead). While this is possible, before I do so, I would like to check if there is perhaps another solution?
The documentation for The Java AWT Native Interface quotes the source comments - struct jawt_DrawingSurface):
First:
/*
* JAWT_DrawingSurface
* Structure for containing the underlying drawing information of a component.
* All operations on a JAWT_DrawingSurface MUST be performed from the same
* thread as the call to GetDrawingSurface.
*/
and later:
/* Cached reference to the Java environment of the calling thread.
* If Lock(), Unlock(), GetDrawingSurfaceInfo() or
* FreeDrawingSurfaceInfo() are called from a different thread,
* this data member should be set before calling those functions.
*/
JNIEnv* env;
I read the second paragraph as "it is possible to call the functions from a different thread, but a special care needs to be taken". What is not clear to me is: how do I set this data member before calling those functions? Is this something that can be done from Java, or do I need a native code for that?

paintcomponent repeats itself without any user interaction

I'm working on a project which uses paintcomponent.
The problem is that this paintcomponent method is executing itself repeatively without asking.I discovered this problem by creating a counter that raises the method runs everytime and I printed this out. Now is see that the method repeats itself randomly.
The problem is that this makes message boxes etc execute multiple times and freeze.
How can I solve this?
paintComponent is a low-level method which can be called at any time at the discretion of the GUI engine. It is not a place to instantiate any message boxes or similar, but to use low-level 2D graphics calls to paint your custom component. Your use case may actually call for a different mechanism whereby to refresh your screen.

Updating scenes in advance while still rendering previous frame

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.

In swing-java, where does the Graphics instance come from?

When an update request is delivered to swing (either system triggered e.g. because of a resize or a block by another window, or app-triggered e.g. by a call to repaint() method), how is this request actually handled? What procedure takes place in that RepaintManager thing?
From your comment:
Do you know what happens in peer.getGraphics()?
That depends on which peer implementation is used.
One implementation is WComponentPeer (used when running on Windows), which seems to use two ways for getting the Graphics object:
If the component has a parent of type Window (or is one itself) which in turn has a back buffer immage associated, that image's Graphics object is returned. This depends on the type of image but is most likeley a SunGraphics2D instance, created in createGraphics().
Otherwise a ScreenUpdateManager instance is retrieved and createGraphics(...) is called on it which in turn returns a new SunGraphics2D instance.
Please note that this is just one possible way and it highly depends on the OS, the JVM and UI toolkit used.

multithreading for java graphics

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).

Categories