invalidate()

Tutorials concerning the OpenGL® ES cross-platform API for full-function 2D and 3D graphics on the Google-Android platform.

invalidate()

Postby nicholas.hauschild » Thu Dec 10, 2009 5:49 am

Greetings all,

I am on my first venture with Android, and I have a question:

I am trying to draw things by using the touch screen. I get everything to draw but in order to force the app to draw each time I am calling View.invalidate(); This clears the screen and force calls View.onDraw(); which is what i want, but I do not want the screen to be cleared every time. So I am looking for a method call that will call View.onDraw(), but will not clear the screen like View.invalidate();

Does this exist? Or would I simply call View.onDraw() from within my View.OnTouchListener.onTouch()?

Thanks!
-Nick
nicholas.hauschild
Master Developer
Master Developer
 
Posts: 310
Joined: Fri Dec 04, 2009 4:50 am

Top

Postby hardcoras » Thu Dec 10, 2009 5:11 pm

GLSurfaceView has a method requestRender() (if you are using RENDERMODE_WHEN_DIRTY).
And if you are using RENDERMODE_CONTINUOUSLY then new frame rendering starts after the previous ends.

To clear the screen use gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
hardcoras
Experienced Developer
Experienced Developer
 
Posts: 62
Joined: Sat Nov 14, 2009 2:31 pm
Location: Lithunia

Postby nicholas.hauschild » Thu Dec 10, 2009 5:42 pm

Thank you for the quick reply.

I currently do not want to venture into the OpenGL side of Android if possible. Is there a way to do something like this without going to OpenGL ES? If not I may have to make my first venture with Android an ad-venture. :D

Thanks again!
-Nick
nicholas.hauschild
Master Developer
Master Developer
 
Posts: 310
Joined: Fri Dec 04, 2009 4:50 am

Postby hardcoras » Thu Dec 10, 2009 5:48 pm

You can draw using Canvas.
There are two options 1) to draw on a View, and 2) to draw using SurfaceView.

You can read about it in Android Developers Guide: http://developer.android.com/guide/topi ... ith-canvas
hardcoras
Experienced Developer
Experienced Developer
 
Posts: 62
Joined: Sat Nov 14, 2009 2:31 pm
Location: Lithunia

Postby nicholas.hauschild » Fri Dec 11, 2009 2:37 am

I am drawing with the Canvas. The View.onDraw() method passes in a Canvas, and that is what it is that I am applying my 'drawings' to.

Here is a sample of what I am doing:

Syntax: [ Download ] [ Hide ]
Using java Syntax Highlighting
  1.  
  2.         @Override
  3.  
  4.         public void onDraw(Canvas canvas) {
  5.  
  6.                 paint.setColor(currentColor);
  7.  
  8.                 canvas.drawLine(line.prev.x, line.prev.y, line.cur.x, line.cur.y, paint);
  9.  
  10.         }
  11.  
  12.  
Parsed in 0.030 seconds, using GeSHi 1.0.8.4


I update the line member variable and then invalidate() my View in the onTouch() method of my OnTouchListener class. But invalidate() clears the Canvas, where I want to add to my Canvas. This is a requirement of mine so that I only need to draw one line per call to onDraw(), I am trying to be as performant as possible.

Hopefully that clears some things up. Thanks for the replies!
-Nick
nicholas.hauschild
Master Developer
Master Developer
 
Posts: 310
Joined: Fri Dec 04, 2009 4:50 am

Postby hardcoras » Fri Dec 11, 2009 9:52 pm

I don't use Canvas, but here is extract from Android developers page http://developer.android.com/guide/topi ... urfaceview

"Note: On each pass you retrieve the Canvas from the SurfaceHolder, the previous state of the Canvas will be retained. In order to properly animate your graphics, you must re-paint the entire surface. For example, you can clear the previous state of the Canvas by filling in a color with drawColor() or setting a background image with drawBitmap(). Otherwise, you will see traces of the drawings you previously performed."


And it says clearly that Canvas should be cleared explicitly.
Maybe you are doing something wrong. Just attach Android source code and debug. I do it all the times when I don't know what a system is doing under hood.
hardcoras
Experienced Developer
Experienced Developer
 
Posts: 62
Joined: Sat Nov 14, 2009 2:31 pm
Location: Lithunia

Top

Postby nicholas.hauschild » Sat Dec 12, 2009 6:55 pm

Thanks for the help hardcoras!

It is my understanding that the SurfaceView is for OpenGL ES development, and that is something I would like to start on sometime soon. But for my current project I am seeing what I can do without OpenGL.

I thought I would share with all how I solved my problem:

I moved away from trying to draw lines and points over top of my previous Canvas. Instead, I am now maintaining an int array of 'pixels', where each pixel represents a pixel on the screen and the int held at each index is the color of that pixel. In my onDraw() method I call Canvas.drawBitmap() and I feed it my 'pixel' array, and it works great.

I look forward to working with this community, whether that means asking for help or giving it where I can.

Thanks again!
-Nick
nicholas.hauschild
Master Developer
Master Developer
 
Posts: 310
Joined: Fri Dec 04, 2009 4:50 am

Postby hardcoras » Sat Dec 12, 2009 10:51 pm

Hi,
i had some beer and whiskey today, so not much help from me. But one thing for sure that SurfaceView does not requires opengl, GLSurfaceView does.
SurfaceView can be used with Canvas, take a look at Lunar Lander example.

Your solution can be a way around your problem. I always clear my screen before drawing new frame (but I'm using opengl).

Anyway good luck in your project.

BR,
Arunas
hardcoras
Experienced Developer
Experienced Developer
 
Posts: 62
Joined: Sat Nov 14, 2009 2:31 pm
Location: Lithunia

Flickering Canvas when no repaint takes place.

Postby karnbo » Fri Feb 12, 2010 3:49 pm

Also the Lunar Lander example is redrawing everything everytime. BTW. Thanks for the thread.

Extending SurfaceView, the entire display needs to be redrawn every time, to avoid flickering screen. Yes, the previous drawing is probably not lost, but the screen is updated with junk in between. Is this a bug?

The code (in doDraw()):
-----------------------------
if(bFirstTime){
bFirstTime = false;
Rect r = new Rect( 0, 0, canv.getWidth(), canv.getHeight());
Paint paint = new Paint();
paint.setColor(Color.BLUE);
canv.drawRect(r, paint);
}
-----------------------------
makes the screen flicker, while the code
-----------------------------
Rect r = new Rect( 0, 0, canv.getWidth(), canv.getHeight());
Paint paint = new Paint();
paint.setColor(Color.BLUE);
canv.drawRect(r, paint);
-----------------------------
keeps a steady blue color.

Maybe I should look at the OpenGL option you talk about. Or anyone who've seen another solution to the problem?
Attachments
FlickeringCanvas.tar.gz
(18.83 KiB) Downloaded 131 times
karnbo
Freshman
Freshman
 
Posts: 3
Joined: Fri Feb 12, 2010 3:40 pm

Workaround is to draw into a bitmap

Postby karnbo » Fri Feb 12, 2010 4:49 pm

Me too found a work around. Guess more people will get this problem... if your not all smarter than me and figure this out instantly... Not the best solution, but at least I dont have to repaint everything every time.
--------------------------------------
Bitmap mGamebitmap = Bitmap.createBitmap(canvas_out.getWidth(), canvas_out.getHeight(), Bitmap.Config.RGB_565);
....
Canvas canv = new Canvas(mGamebitmap);
if(bFirstTime){
bFirstTime = false;
Rect r = new Rect( 0, 0, canv.getWidth(), canv.getHeight());
Paint paint = new Paint();
paint.setColor(Color.BLUE);
canv.drawRect(r, paint);
}
canvas_out.drawBitmap(mGamebitmap, 0, 0, null);
--------------------------------------
This way the 'canvas_out' is updated completely every time, but the mGamebitmap is changed when needed. No flickering screen.
karnbo
Freshman
Freshman
 
Posts: 3
Joined: Fri Feb 12, 2010 3:40 pm

Top

Return to Android 2D/3D Graphics - OpenGL Tutorials

Who is online

Users browsing this forum: No registered users and 2 guests