I have a UI that haes a GLSurfaceView that shows a polygon.
The UI haves also two buttons ZoomIn and ZoomOut. When the user press these buttons, the zoomIn() and zoomOut() methods of myGLSurfaceView are called.
The problem is that i want that the method onDrawFrame get's called to get reflected the zoom in & out.
Why i want this? because the buttons have setClickable(true); why? because i need that if the user leaves the finger presing the button, the zoom get's applied continuosly until the user releases the buton.
Now it works but it works bad, i need to refresh the GLsurfaceview forcing onDrawFrame
Call gLSurfaceView.requestRender(). This will (from link):
Request that the renderer render a frame. This method is typically used when the render mode has been set to RENDERMODE_WHEN_DIRTY, so that frames are only rendered on demand. May be called from any thread. Must not be called before a renderer has been set.
solved using threads and press/release events of the finger
Related
I am using SurfaceView with ndk+openGL, when press screen rotate button of the emulator,
i received SurfaceChanged event from SurfaceHolder.Callback, then i post a redraw message via Handler, and the Handler redraws the screen with new display metrics via JNI native code, but the display is broken, as the picture shows.
I sure that the native OpenGL drawing code already draws one frame, after press rotate button and before screen rotation finish, but don't know why the display is broken.
I'm not so familiar with android, could someone help me. thanks.
EDIT:
when i make some touch events to trigger new frames, the display got fixed.
so i'm thinking is there a rotate finish event, so i can force draw one frame to fix this issue.
Problem solved.
Override the surfaceRedrawNeeded method of SurfaceHolder.Callback2, it will be called after rotate finished.
I have made a "2048 game" with java in Eclipse . All things is good and work correctly, even the animation of cells that move in 4 directions.
But the problem is, that the animation does not work fine & smooth, I think because of heavy processing load.
I have made a class that extends ImageView. and I have overridden the
onDraw() method. Then in another method and in a thread, I call the postInvalidate() method frequently for the animation (so the onDraw() method is called frequently).
My algorithm in the onDraw() method is fine and my animation runs correctly but I think using this way (using ImageView class and calling onDraw() method frequently) is not an accurate way, because the onDraw() method redraws everything unnecessarily. Some things in this game are fix and do not need to be redrawn, so this way the process is heavy and I don't like this.
Is there another way for this game, than drawing the page frequently for animation without jumping? thank's for your answer .
I am setting up a game loop. The loop is set to update at 50 FPS. Currently the only action the app does is draw screen coordinates on response to touch events. Originally I set up the draw function to only draw new touch events. This caused the text to blink. Multiple touch events blink at different times, which leads me to think that Canvas uses multiple pages behind the scenes. In an effort to get around this I made a list of every touch event that happened and on every draw call I redraw the entire list.
Please correct me if I am wrong, the lockCanvas()/unlockCanvasAndPost() calls are in essence a backbuffer swap. Reading the documentation on locking and unlocking it sounds like it is necessary to redraw the entire scene between calls unless you use lockCanvas(Rect dirty). In this case the dirty rect area needs to be redraw while the outside area is preserved.
The content of the Surface is never preserved between unlockCanvas()
and lockCanvas(), for this reason, every pixel within the Surface area
must be written. The only exception to this rule is when a dirty
rectangle is specified, in which case, non-dirty pixels will be
preserved.
I know it sounds like I've answered my own question, but according to the documentation the Surface is never preserved between calls. However this does not explain the behavior of my first implementation, which was I would tap the screen and the text would start blinking. Since I only drew the text one time, this would mean that the blinking is from swapping to the "backbuffer" which didn't get the drawText() call, and the original Surface which did not get destroyed but perhaps it is to be considered unreliable.
So, the question: Do I need to redraw all objects on each draw call? And if so, do I need to "clear" the canvas, or at the least redraw the background image also?
yes, unless you're doing a dirty redraw where you define the region that you are redrawing, every point on your canvas gets destroyed.
How do I call onDraw() on my class extending GLSurfaceView. I need the canvas for drawing the gestures of the user. (FingerPaint.java logic). Mean while I need the onDrawFrame() of the renderer to be called for other effects. I can manage the calls to both the methods by maintaing a flag. I am calling invalidate() but that too is not able to call the onDraw(). GLSurfaceView extends View so I thought I can override onDraw() and can call it by calling invalidate(). Please Throw some light. Thanks in Advance Krishna :)
Try calling requestRender () from your GLSurfaceView.
Obviously this works best when setting rendermode to "RENDERMODE_WHEN_DIRTY".
And that means you won't be rendering continuously, so that may interfere with the "constant" rendering required for your effects.
I think the best solution would be to split the rendering up between 2 overlaying surfaces and 2 renderers. Request the bottom surface (fingerpaint surface) to render a frame whenever the user interacts, and on the top one (gfx surface) you render continuously. Or swap this around... whatever works best.
Just call invalidate() and onDraw() will be called, just like normal View. The canvas is drawn on top of the GLES viewport.
So far I couldn't implement invalidate(Rect dirty). The whole view is redrawn always.
It is needed to put setWillNotDraw(false) before drawing.
I need to redraw the overlay after the user zooms.
What is the best way to do this?
I've tried everything I can think of (saving a getZoomLevel() state, overriding onUserInteraction()), nothing actually works.
The problem is, that draw() is being called when the user clicks zoom, so the information my draw method gets (About the map's state) is different from the state after the mapview finishes zooming.
Also, draw() isn't being called at the end of the zoom, so only if I pan the map the overlay is actually being drawn properly.
As nobody has answered this in 7 months, I will write what I ended up doing.
I used a Handler to refresh the map manually after 500ms, it worked alright.
Handler handler;
handler.postDelayed(refreshRoute, 500);
Have you tried calling mapview.postInvalidate() after the zoom?