I am working on a map engine. I would like to let user rotate the map. If I do the rotation by standard drawing on canvas, it will slow down the phone and the map tiles rotated by standard canvas API looks bad.
I found some OpenGL frameworks for Android on the Internet. But none of them do what I want. Most of them cannot use Android standard components within the OpenGL Activity.
I want to put a custom view that drawn by OpenGL to a Layout component (eg, LinearLayout). Thus, I can put everything (including OpenGL layout) to a Activity. I am sure that it can be done by using standard Android OpenGL API. But the OpenGL draw is too difficult to me.
Is it any OpenGL framework to let me draw a custom view by OpenGL? All I need is a framework that supports simple drawing.
Its called GLSurfaceView.
In one of my projects I have this:
public static GLView glSurfaceView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
glSurfaceView = new GLView(this);
setContentView(glSurfaceView);
}
Make sure the class you make extends the GLSurfaceView.
public class GLView extends GLSurfaceView
In the GLView class you will have to have this:
private GLRenderer _renderer;
public GLView(Context context) {
super(context);
_renderer = new GLRenderer(context);
setRenderer(_renderer);
}
The GLRenderer class will implement GLSurfaceView.Renderer
Atleast this is what I think you are asking. If not post comment below and I will try and answer it better.
It's a shame that you gave up on OpenGL, I've recently discovered it and find it heaps better then doing standard drawing. Using textures instead of keeping images as Bitmap objects takes much better advantage of device's memory (especially on the pre Honeycomb devices) and if you use an orthogonal projection you don't need to bother with a good portion of OpenGL's fancy 3d stuff. Plus, you no longer have to care (as much) about various devices resolutions so that all the stuff you put on screen is well proportioned (you still have to care about width and height ratio's but that's a lot better).
Related
I got a problem with drawing a mapView from the here-api into a glSurfaceView (it should be a glSurfaceView as some external devices requeres it to ensure good performance).
The map draws into a normal SurfaceView just perfectly.
I do the following steps to create the map-view in the GLSurfaceView:
Extend my view from GLSurfaceView:
public class MapView extends GLSurfaceView
Setting the Renderer uppon initialisation in the ctors:
setRenderer(...)
Start rendering after the map has been initialized:
Renderer renderer = new MapOffScreenRenderer(getContext());
renderer.setMap(map); //mapView, not null
updateRendererSize(); //update the render size to the screen size
renderer.start(getHolder(), surfaceUpdatedListener); // HERE COMES THE CRASH
It seems like the MapOffscreenRenderer crashes if i try to tell him to draw the map into the glSurfaceView.
The crash is a generic error: "12291 EGL_BAD_ALLOC during rendering".
If i try to call the renderer.start() func (without the holder param), then everything is fine (the only bad thing is that the map is not being drawn).
The GlSurceView initialisation itself is fine as i am able to draw my own geometries into it.
Thank you very much for you help.
MapOffScreenRenderer internally uses a PBuffer backed surface and its own rendering thread and EGL context. It is not intended to be used to push into another GLSurfaceView surface. If you really want to do this then maybe create an independent OpenGL surface and share it between the GLSurfaceView and the MapOffScreenRenderer.
What use case are you try to accomplish using this type of design?
I am trying to develop an android application to display a zoom-able, pan-able map, (which is just a bitmap image), that also allows the user to click on certain points on the map.
I am struggling to find the most effective way of implementing such an app. After trying numerous other methods, (including Webviews, OpenLayers), the best way, (according to this site at least), seems to be using a SurfaceView with a Canvas. The code I have so far is pieced together from snippets I found all over the internet, so it just crashes. I have included it here anyway in the hope it gives some idea of what I am trying to achieve:
public class Main extends Activity {
private Bitmap bmp;
private SurfaceView surfaceView;
#Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
surfaceView = (SurfaceView)findViewById(R.id.surface);
bmp = BitmapFactory.decodeResource(getResources(),
R.drawable.testmapbmp);
//decode the bitmap file
Canvas canvas = new Canvas(bmp);
//create a canvas from the bitmap, then display it in surfaceview
surfaceView.draw(canvas);
}
}
Is this the best way to achieve the functionality I want for my application? Or is there a better way, especially if I could run into problems later on, implementing the clickable sections of the map, for example.
I really need help from someone who has created something like this before, so I can get my train-of-thought on the problem, but I greatly appreciate any help/pointers/tips at all!
Thanks
Your piece of code is not really correct.
Usualy if you want to do this kind if things you need to create your own custom view (either by inheriting View or SurfaceView). In your View subclass you need to override method onDraw(Canvas) and draw your bitmap on canvas by using one of canvas methods.
To make it pannable and pinch-zoomable you need to use Scroller and ScaleGestureDetector classes. Usually panning or scaling is done by applying affine transformations to a canvas by using it's methods (rotate, scale, translate).
Difference between SurfaceView and View is that in SurfaceView you can draw directly from separate thread, which means you can organize sort of rendering loop there and draw from it. It is good for simple games and animation effects. I believe, for purpose of drawing a bitmap this is overkill and much simpler to subclass View.
I'd start with this and this, if I were you.
I'm currently developing a game, which only uses 2D graphics.
In the game i extensively use android's SurfaceView to display my graphics.
I've heard that GLSurfaceView uses Hardware-accelerated graphics, and i can increase performance of my app using that instead of the current SurfaceView.
Currently, i have a class extending SurfaceView, which updates and renders the game state, when methods update() and render() are called by my own thread class extending Thread. The Thread basically helps me maintain a nearly constant FPS.
NOW THE PROBLEM:
How do i change from SurfaceView to GLSurfaceView, and call methods to update and render game state from the Thread, to still have control over the FPS. I read the android documentation on OpenGL ES, and i can't quite understand how to use the GLSurfaceView.Renderer.
If someone can explain how can i easily switch from SurfaceView to GLSurfaceView, It'd be of great help! Thanks!
The Class that displays your game will extend GLSurfaceView. Your rendering class will implement Renderer. In your Renderer class you will need to add these unimplemented methods: onDrawFrame(), onSurfaceChanged(), and onSurfaceCreated().
Hope this helps.
I need to create a game for one of my projects. The game is not a grafic game but I still want it to have nice appearance (maybe 3D background look).
I thought I would use a diferent technique than just to load the background through an xml file. I want to create a surface view with a nice texture background (what I would like is one similar to the live wall papers). I know there is the rendererscript but I apparently it doesn't work on apis level lower than 11??? I would like to target api level 7 or 8.
Here is what I planned to do something like that:
mView = new BasicGLSurfaceView(getApplication());
View inflatedView=View.inflate(this, R.layout.title, null);
View inflatedView2=View.inflate(this, R.layout.buttons, null);
setContentView(mView);
this.getWindow().addContentView(inflatedView,
new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.WRAP_CONTENT));
this.getWindow().addContentView(inflatedView2,
new LayoutParams(LayoutParams.MATCH_PARENT,
LayoutParams.MATCH_PARENT));
I was wondering which way is the best:
use open GLSurfaceView or just normal SurfaceView and Canvas. Which one is faster and will look nicer?
Could you please advice me on the best solution to implement?
thank you
Canvas is simpler, and it's fast, but it doesn't support 3D drawing. Since you said that you might want to do 3D, you would want to use the GLSurfaceView and OGLES. Canvas can often outperform OpenGL for 2D drawing.
I am new in android. I need to use opengl in combination with View Class to draw something. How to do this. plz give me any hints or suggestions...
You also have the option to combine "normal" android views (Button, ImageView, etc) in a layout with a GlSurfaceView. (i.e. FrameLayout)
By doing so you can combine normal android UI with openGL, you can also make a composite view where the openGL view is just part of the layout.
This is the way ads are usually displayed overlaying 3D aplications.
Be aware that this technique can produce quite weird results in low end devices when dealing with tranasparency.
You probably wanta GlSurfaceView. It's a View that allows you to use Opengl to draw to it.
Put it in a layout file for your app
<GLSurfaceView id="#+id/myView" android:layout_width="fill_parent" android:layout_height="fill_parent"/>
Then in your code
((GLSurfaceView)findViewById(R.id.myView)).setRenderer(new GlSurfaceView.Renderer() {
public void onSurfaceCreated(...)...
public void onSurfaceChanged(...)...
public void onDraw(GL10 gl)...
});
((GLSurfaceView)findViewById(R.id.myView)).setRenderMode(RENDERMODE_CONTINUOUSLY);
And then you draw in your onDraw with your gl calls.
This is the super-quick start answer to your question, if you drop the surfaceview in framelayout and know what your drawing it's pretty quick to get a basic setup running.