Combining a Canvas and OpenGL ES Renderer? - java

I have an app that uses a Class with an extension SurfaceView to draw to a canvas, but i'm looking at moving over to openGL. I noticed that if I merely change the SurfaceView extension to a GLSurfaceView, the app still runs the same. I've also been able to start basic drawing in another app using openGL ES.
I took it the next step and instantiated another class for the renderer in GLSurfaceView, and I instruct the render to draw a triangle. This all compiles and runs fine, but it runs exactly like the original App, with no triangle rendered, but the rest of the canvas draws properly.
I can't think of why it's not rendering, or why it wouldn't render. Or maybe it is rendering, but it's simply being overridden by the canvas?
I know it seems odd to try to use both methods, Since my app is live, I would rather implement switching the rendering over to GL at my own pace so that it doesn't take me a month to get the next update out.
So Anybody ever tried do do this? Run a Gl renderer OVER a canvas?

You cannot use both OpenGL and a Canvas to render on a single SurfaceView. You can however put another View on top of the SurfaceView to achieve the desired effect.

Try the following:
addContentView(SurfaceView);
addContentView(GLSurfaceView);
or create a relative layout with both views.

Here my sample code when adding canvas over the OpenGL view, thanks to #Audrius Butkevicius !
mGLView = new MyOpenGLSurfaceView;
// SET OpenGL View
setContentView(myOpenGLView);
mCanvasOverlayView = new View(context)
mOverlayViewParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT);
// ADD Canvas view overlay
addContentView(mCanvasOverlayView, mOverlayViewParams );

Related

How to copy a complicated ViewGroup to a bitmap?

Can not make a bitmap from a complicated view with state machine.
I have a RelativeLayout in which a dynamic tree of views handles touchevents to draw graphics. It uses a state machine to keep track of events like down, move and up and perform various drawing activities.
Now I want to make a copy (bitmap) of this RelativeLayout every time the view changes and display on the second screen. I have tried both methods I found online:
draw(theSecondCanvas);
Bitmap cache = getDrawingCache();
Both work most of time except occasional failure. The problem is both methods will eventually call every child views' draw() one more time to draw on the second canvas. But the state machine has changed to the different state based on the last touch event. It gives different drawing result or sometime error with null object reference because the additional drawing request has no touch event associated with it.
One option is for me to fix the complicated logic of state machine in the tree of views so it can handle an additional stateless drawing on the second canvas.
But I would think it has to be a simpler way to capture a bitmap from a view without drawing everything again. The view has done all the drawing inside already. It doesn't make sense to repeat the same work on the second canvas just to get a copy of bitmap.
Any suggestions? Thanks in advance!
I realized that off-screen rendering is not necessary in my case. I can intercept default canvas and draw on my own canvas with a bitmap. Then copy the bitmap to the default canvas. This solves the problem.

Is there a proper way to scale actors on the Stage?(Libgdx)

I'm making an android app which has Libgdx Stage handling the HUD. But how can I scale things I add to Stage?
I've tried some manipulations with Camera, Viewport, and none of the work properly. Let's say I want my ImageButton placed in the right top corner of the screen. I managed to do that manipulating with table positioning, it seems to be fine. But the problem appear when I run my app on my phone. The ImageButton positioned right but it's kinda small :-)
Thing is I want ImageButton look like on (540,800) resolution screen.
ImageButton is (65,65).
When it comes to bigger screensizes ImageButton starts to look small because it does not scale(or the viewport and camera stuff dont work well, I dont think the actual scaling is truly necessary)
I suggest you to check the documentation about Viewports, which is pretty clear, although a bit dated : https://github.com/libgdx/libgdx/wiki/Viewports
If you don't need to mess with the camera, don't bother to declare one. Simply use a stage, with includes automatically an orthographic camera. If you declare an Actor within the bounds of the viewport, it should scale properly depending on the type of viewport you selected. For instance :
FillViewport vp = new FillViewport(800, 1280); // fills the screen, adapting itself to actual screen ratio
Stage stage = new Stage(vp);

How to create a custom Android view? Using XML objects or a drawing API?

I'm trying to create a new view that would:
load an image
allow the user to zoom and rotate the image with two fingers while a "cropping box" stays translucent over the top while the image extends beyond the "cropping box"
with the end goal of being able to mark the rotation and position of the main image (so that later i could crop out or show the area within the cropping box)
I'm wondering if I can do this with an ImageView holding the image in the background and another ImageView holding the crop box on top of it, then using TouchEvents to move the image, would this work?
Or do I need to use some drawing API on a 2D surface?
I'm just really new to creating custom objects in Android that aren't just customized out-of-the-box Views.
What's the standard way of creating something like this?
Thanks!
Create a Compound View by extending RelativeLayout with two overlapping ImageViews in it. Then override onTouch event or override onGestureDetector interface in that newly created View.
Official Documentation: http://developer.android.com/guide/topics/ui/custom-components.html
Another Tutorial: http://www.vogella.com/tutorials/AndroidCustomViews/article.html

Should I draw using the View or Canvas class in Android?

I'm developing for Android and am a little confused about what is the best way to write 2d full-screen games. On my desktop PC version of my game I create a class which extends the Canvas class and go from there, overloading the update() method to draw to the screen. My intention is to port it to Android.
However I've noticed some online tutorials don't use Canvas, and use View instead. I'm used to using Canvas and drawing with Graphics objects using drawImage(), for example.
Is there a best (i.e. fastest, most accepted) choice out of the two (Canvas or View) or doesn't it matter. Perhaps one extends the other anyway?
A view is your base widget, think of it sort of like a blank panel to which other widgets can be added, or with which you can implement your own widgets. A view has a draw method you can override which takes a canvas as a parameter. You do your rendering in that method. The draw operators you are looking for should be available from the Paint class, which draws to a Canvas.

GLSurfaceView/SurfaceView overlap

I asked a question about this earlier but received no responses, so I'm trying again.
I need to do a rendered 2D picture with some accompanying labels and graphics on a Motorola Xoom, Android 3.0. Although what I need can be done with just a SurfaceView (Canvas) or just a GLSurfaceView, I would really like to use both because the rendering is faster with the GLSurfaceView, and the labeling and graphics are easier with the SurfaceView. The visual layout is as shown below.
I tried to put the SurfaceView on top by declaring it in the layout XML after the GLSurfaceView. The SurfaceView is transparent (except for where I explicitly draw stuff) so that the GLSurfaceView can still be seen.
This approach has worked pretty well with one huge exception. Anything that I draw on the SurfaceView that is in the GLSurfaceView region does not show up at all. To verify this I drew some text that was right on the boundary (some in the shared region, some just in the SurfaceView region), and it was chopped off at the GLSurfaceView boundary. I have tried using the "bringToFront" method to fix this, but it hasn't worked.
Can anyone give me some ideas on why this isn't working or what I can do about it? Is it that the GLSurfaceView is in front, or is that the GLSurfaceView writes directly to the video memory, so it doesn't matter if something is in front of it?
The way SurfaceViews work will make it impossible to do what you want. You will have to render your text inside the GLSurfaceView.
Never try to overlap a GLSurfaceView with anything (above or below). At best it breaks on your device and you catch it early, at worst it works on one device and not others. Bite the bullet and do everything in a GL view or none of it. If you need the speed then GL is the way to go.
we should set setZOrderMediaOverlay and setZOrderOnTop to true value
setZOrderMediaOverlay
Added in API level 5
void setZOrderMediaOverlay (boolean isMediaOverlay)
Control whether the surface view's surface is placed on top of another regular surface view in the window (but still behind the window itself). This is typically used to place overlays on top of an underlying media surface view.
Note that this must be set before the surface view's containing window is attached to the window manager.
Calling this overrides any previous call to setZOrderOnTop(boolean).
setZOrderOnTop
Added in API level 5
void setZOrderOnTop (boolean onTop)
Control whether the surface view's surface is placed on top of its window. Normally it is placed behind the window, to allow it to (for the most part) appear to composite with the views in the hierarchy. By setting this, you cause it to be placed above the window. This means that none of the contents of the window this SurfaceView is in will be visible on top of its surface.
Note that this must be set before the surface view's containing window is attached to the window manager.
Calling this overrides any previous call to setZOrderMediaOverlay(boolean).
Please refer to this link :
http://developer.android.com/reference/android/view/SurfaceView.html#setZOrderMediaOverlay(boolean)

Categories