OPENGL ES MatrixGrabber and GLU.gluUnproject() mayhem - android

[EDIT] Ignore this post, it was a noob's mistake [/EDIT]
I started Android last week (= I'm pretty new to it :) ) and I'm banging my head on a problem:
I try to perfom a raycasting to get the objects under a point of the screen.
I found out that the GLU.gluUnproject method was what I needed, after a decent amount of failures, I found a solution
I've copied the MatrixGrabber, MatrixStack and MatrixTrackingGL classes in my project, they seem fine.
the method I use goes as follow:
static public Vertex unProject( float x, float y, World world )
{
world.mg = new MatrixGrabber();
world.mg.getCurrentState(world.gl);
float[] pos = new float[4];
GLU.gluUnProject( x, y, 0f,
world.mg.mModelView, 0,
world.mg.mProjection, 0,
world.view().get_size(), 0,
pos, 0);
return new Vertex(pos[0], pos[1], pos[2]);
}
Vertex is a dataHolder with x,y,z floats
World extends GLSurfaceView, I do the GLWrapper replacement in the constructor:
world.mg is a MatrixGrabber()
public World( Context context )
{
super(context);
[...]
//allows matrix manipulation
setGLWrapper( new GLWrapper()
{
public GL wrap(GL gl)
{
return new MatrixTrackingGL(gl);
}
});
}
and I make sure that all the variables are instanciated when I do my call
but still I can't get this to work: the app crashes badly on the
world.mg.getCurrentState(world.gl);
call.
it also crashes it on getCurrentModelView(gl); and getCurrentProjection(gl);
I'm using Android 1.5, but tried with other versions up to 3. same thing.
I don't really know which version of OpenGLI'm using ; the GL10 is used everywhere, I don't know if it is important, all I've read concerned the GL10 "Type".
if anyone has a clue, an advice, a workaround or a solution, I'd be happy happy happy
and anyway, thanks for reading :)

private void getMatrix(GL10 gl, int mode, float[] mat) {
MatrixTrackingGL gl2 = new MatrixTrackingGL(gl);
gl2.glMatrixMode(mode);
gl2.getMatrix(mat, 0);
}
replace the casting on the first line of the MatrixGrabber.java

my World class extended GLSurfaceView and was using the MatrixTrackingGL as a wrapper.
the problem was that the Viewport also extended GLSurfaceView and was NOT using the MatrixTrackingGL... stupid.
now the world doesn't extend anything and the Viewport ( extending GLSurfaceView ) implements the Wrapper's change and everything's fine.

Related

How to 'exchange' the Renderer in a GLSurfaceView instance in android?

In android I have taken a rotating sphere example given here. It creates a simple app showing a rotating sphere (the earth).
Now, in a class derived from GLSurfaceView I wait for an even (like a touch-screen event) in order to exchange the renderer. I want the current renderer to stop rendering, and the GLSurfaceView should use a different renderer instead (to display some other object).
I have tried to use the following code:
public class MyGLSurfaceView extends GLSurfaceView {
Context mycontext;
MyGLSurfaceView(Context context) {
super(context);
mycontext = context;
}
public boolean onTouchEvent(MotionEvent event) {
int x = (int)event.getX();
int y = (int)event.getY();
Log.d("onTouchEvent",String.format("keyCode: %d coords: %d %d", event.getActionMasked(), x, y));
GlRenderer renderer = new GlRenderer(mycontext);
setRenderer(renderer);
return super.onTouchEvent(event);
}
}
which gives the following error:
FATAL EXCEPTION: main
Process: com.jimscosmos.opengltexturedsphere, PID: 25708
java.lang.IllegalStateException: setRenderer has already been called for this instance.
I guess I have to stop/remove/destroy the 'old' renderer, but I did not find anything useful for that in the documentation. Maybe my approach is completely wrong? What else to do? How to do it right?
If you insist, technically it can be achieved using a 'mediator' - as suggested here: Change GlSurfaceView renderer.
However - I think this is an overhead you really do not need. Simply prepare various objects and change the various rendering properties in a single renderer.

Random Sprite with Sprite Pool

I wanna know how Sprite Pool works, since I dont really understand them.
What I'm trying to do is show random sprites each time user touch the button (I already manage the control), but my code doesn't seem right, because it only shows the same sprite again and over again.
This is my code :
public class SpritePool extends GenericPool<Sprite> {
private ITextureRegion mTexture1, mTexture2, mTexture3, mTexture4, mTexture5;
private VertexBufferObjectManager mVertexBufferObjectManager;
private Sprite sprite = null;
public SpritePool(ITextureRegion pTextureRegion1, ITextureRegion pTextureRegion2, ITextureRegion pTextureRegion3
, ITextureRegion pTextureRegion4, ITextureRegion pTextureRegion5, VertexBufferObjectManager pVerTexBufferObjectManager){
this.mTexture1 = pTextureRegion1;
this.mTexture2 = pTextureRegion2;
this.mTexture3 = pTextureRegion3;
this.mTexture4 = pTextureRegion4;
this.mTexture5 = pTextureRegion5;
this.mVertexBufferObjectManager = pVerTexBufferObjectManager;
}
#Override
protected Sprite onAllocatePoolItem() {
YesOrNoActivity.setRoll_1(MathUtils.RANDOM.nextInt(5) + 1);
switch(YesOrNoActivity.getRoll_1()){
case 1:
sprite = new Sprite(0, 0, this.mTexture1, this.mVertexBufferObjectManager);
break;
case 2:
sprite = new Sprite(0, 0, this.mTexture2, this.mVertexBufferObjectManager);
break;
case 3:
sprite = new Sprite(0, 0, this.mTexture3, this.mVertexBufferObjectManager);
break;
case 4:
sprite = new Sprite(0, 0, this.mTexture4, this.mVertexBufferObjectManager);
break;
case 5:
sprite = new Sprite(0, 0, this.mTexture5, this.mVertexBufferObjectManager);
break;
}
return sprite;
}
public synchronized Sprite obtainPoolItem(final float pX, final float pY) {
Sprite sprite = super.obtainPoolItem();
sprite.setPosition(pX, pY);
sprite.setVisible(true);
sprite.setIgnoreUpdate(false);
sprite.setColor(1,1,1);
return sprite;
}
#Override
protected void onHandleRecycleItem(Sprite pItem) {
super.onHandleRecycleItem(pItem);
pItem.setVisible(false);
pItem.setIgnoreUpdate(true);
pItem.clearEntityModifiers();
pItem.clearUpdateHandlers();
}
}
Hope you guys can help me out, thanks :)
I'm going to show you a simple cow pool from my application to give you an idea of how the pools work. My CowPool is used as a source to generate CowCritters (NPC cows that walk around, graze, and generally do the things you'd expect from cows). Here's the code:
public class CowPool extends GenericPool<CowCritter> {
private final String TAG = this.getClass().getSimpleName();
public CowPool() {
super();
}
#Override
protected CowCritter onAllocatePoolItem() {
return new CowCritter();
}
protected void recycle(CowCritter cow) {
this.recyclePoolItem(cow);
}
}
You'll see there are two methods, one that allocates a pool item (generates a new cow) and another that recycles the cow. When I need a cow, I don't call either of these methods, instead I call cowPool.obtainPoolItem(). If the pool has a cow in it, it will return the cow. If it doesn't, it will call onAllocatePoolItem(), creating a new cow, and it will return that cow. When I'm done with a given cow, I throw it back in the pool using the recycle() method.
What's the point of all this?
Well first of all note that I don't have to do any of this. Instead I could just instantiate a new cow when I need one, and throw it away. The key point to understand is that when I instantiate a new cow, that has overhead. It assigns memory resources. And so forth. Similarly, when I dispose of a cow, that has resources too. At some point the garbage collection is going to have to clean-up said cow, which takes a little bit of processing time.
Pooling is essentially just a form of recycling. I know I'm going to need a cow again in the future, so rather than permanently dispose of this cow, I stick it in the pool, and later, when I need a cow, the cow is there for me. No garbage collection is involved, because the pool is holding on to the extra cow. And instantiating a new cow is faster because I'm not really instantiating a new cow, the cow is already there in the pool (unless the cow isn't, then it makes one).
It's important to understand also that pooling is a form of optimization. You're not getting new functionality by pooling; instead, you're getting a potentially smarter handling of resources. I say potentially, because it doesn't always make sense to pool objects.
I would suggest that you avoid pooling just for pooling's sake. In other words, make sure you're addressing an actual issue. Profile your code and find out where the real bottlenecks are. If the creation or disposal of objects is taking real time or memory, you may want to start pooling. A perfect opportunity for pooling would be bullets. Imagine you're spraying tons of bullets, creating new ones and disposing of the old ones. In such a case, you might get a real performance benefit by pooling instead.
Hope this helps.

How to draw a bitmapfont on a stage in libgdx?

This is my current render method on my level in my Libgdx game. I am trying to draw a BitmapFont on my level's top right corner but all I'm getting is a bunch of white boxes.
#Override
public void render(
float delta ) {
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
this.getBatch().begin();
//myScore.getCurrent() returns a String with the current Score
font.draw(this.getBatch(), "Score: 0" + myScore.getCurrent(), 600, 500);
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
this.getBatch().end();
}
I would like to add the score font into some kind of an actor and then do a scene.addActor(myScore) but I don't know how to do that.
I followed Steigert's tutorial to create the main game class that instantiates the scene, font, in the AbstractLevel class that is then extended by this level.
So far, I'm not using any custom font, just the empty new BitmapFont(); to use to default Arial font. Later I would like to use my own more fancy font.
Try moving the font.draw to after the stage.draw. Adding it to an actor would be very simple, just create a new class and Extend Actor Like such
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.scenes.scene2d.Actor;
public class Text extends Actor {
BitmapFont font;
Score myScore; //I assumed you have some object
//that you use to access score.
//Remember to pass this in!
public Text(Score myScore){
font = new BitmapFont();
font.setColor(0.5f,0.4f,0,1); //Brown is an underated Colour
}
#Override
public void draw(SpriteBatch batch, float parentAlpha) {
font.draw(batch, "Score: 0" + myScore.getCurrent(), 0, 0);
//Also remember that an actor uses local coordinates for drawing within
//itself!
}
#Override
public Actor hit(float x, float y) {
// TODO Auto-generated method stub
return null;
}
}
Hope this helps!
Edit 1:
Also try System.out.println(myScore.getCurrentScore()); Just to make sure that that isn't the issue. You can just get it to return a float or an int and when you do the "Score:"+ bit it will turn it into a string itself
Well, in this case, you may need to call this.getBatch().end first. Like this:
mSpriteBatch.begin();
mStage.draw();
mSpriteBatch.end();
//Here to draw a BitmapFont
mSpriteBatch.begin();
mBitmapFont.draw(mSpriteBatch,"FPS",10,30);
mSpriteBatch.end();
I don't know why, but it works for me.
I have solved similar problem with white boxes by closing batch before starting drawing stage. That is because the stage.draw() starts another batch and invalidates the previous batch not ended with end().
So in current example I would move this.getBatch().end() before drawing stage:
...
font.draw(this.getBatch(), "Score: 0" + myScore.getCurrent(), 600, 500);
this.getBatch().end();
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
If you are using Scene2D try using stage and actors. There is no need to write long codes, check for the MTX plugin that is very easy to use. You can create an awesome user experience
http://moribitotechx.blogspot.co.uk/

Augmented reality on android

I've just started to develop a project as face detection in the base of augmented reality on android phone. And am new to AR(augmented reality) as so far I contributed and evaluated algorithms for facial determinants but I don't have any idea regarding AR and wanna implement AR in my project So could you experts kindly tell me, where to start and and do I need any additional tools to create AR application( /do I've to add any plugins on IDE(eclipse))? or is there is any other IDE works better than eclipse for AR? please check the below link and give your comments because my projects is completely seems as given link below,
http://www.readwriteweb.com/archives/recognizr_facial_recognition_coming_to_android_phones.php
http://www.blackweb20.com/2010/03/01/recognizr-facial-recognition-on-android/#.TzNswE7xodM
thank you!
AR implementation itself is easy. It is basically just an overlay over preview picture, and you can put whatever you like on this overlay. One working example is contained in this project:
http://sourceforge.net/projects/javaocr/
( there are countles others )
Tricky parts starts from here. For face recognition one typically uses Haar transformation, and there are implementations in OpenCV (and also countles others) - but it is questionable if you can it performant enough in android java code, to be really usefull ( you wil have to do it in native code ). And this is only face recognition - it says you - "hey dude, here is the face. maybe" - not identification.
As for IDE, I prefer IntelliJ IDEA as it is just better java ide (somebody will lynch me right now for it ;) ), and it has better android support. But this is commercial product (free comminity edition is available for free, and individual license is not that expensive)
you can try this code:
public class FaceDetectionActivity extends Activity
{
/** Called when the activity is first created. */
#Override
public void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
//setContentView(R.layout.main);
setContentView(new MyView(this));
}
private class MyView extends View
{
private Bitmap myBitmap;
private int width, height;
private FaceDetector.Face[] detectedFaces;
private int NUMBER_OF_FACES=4;
private FaceDetector faceDetector;
private int NUMBER_OF_FACE_DETECTED;
private float eyeDistance;
public MyView(Context context)
{
super(context);
BitmapFactory.Options bitmapFatoryOptions=new BitmapFactory.Options();
bitmapFatoryOptions.inPreferredConfig=Bitmap.Config.RGB_565;
myBitmap=BitmapFactory.decodeResource(getResources(), R.drawable.faces,bitmapFatoryOptions);
width=myBitmap.getWidth();
height=myBitmap.getHeight();
detectedFaces=new FaceDetector.Face[NUMBER_OF_FACES];
faceDetector=new FaceDetector(width,height,NUMBER_OF_FACES);
NUMBER_OF_FACE_DETECTED=faceDetector.findFaces(myBitmap, detectedFaces);
}
#Override
protected void onDraw(Canvas canvas)
{
canvas.drawBitmap(myBitmap, 0,0, null);
Paint myPaint = new Paint();
myPaint.setColor(Color.GREEN);
myPaint.setStyle(Paint.Style.STROKE);
myPaint.setStrokeWidth(3);
for(int count=0;count<NUMBER_OF_FACE_DETECTED;count++)
{
Face face=detectedFaces[count];
PointF midPoint=new PointF();
face.getMidPoint(midPoint);
eyeDistance=face.eyesDistance();
canvas.drawRect(midPoint.x-eyeDistance, midPoint.y-eyeDistance, midPoint.x+eyeDistance, midPoint.y+eyeDistance, myPaint);
}
}
}
}
this code will detects the face from Bitmap so you should implement this technique also through camera
cheers .

LibGdx returns NULL for a gl object using GL10

I am developing a game using LibGdx, when i tried to run the game in motorola atrix which is of 2.2.2 version, it is not accepting GL10 and giving null for gl object. Can anyone help me on this.
Code below:
public class Game2D implements InputProcessor, ApplicationListener {
public void create() {
//initializing all
}
public void render() {
GL10 gl = Gdx.graphics.getGL10();
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
Gdx.graphics.getGL10().glViewport(
0,
0,
Gdx.graphics.getWidth(),
Gdx.graphics.getHeight()
);
camera.update();
camera.apply(gl);
//-------------------
}
}
It's hard to say without seeing a code snippet, but I feel like you're using GL related stuff before the context is initialized.

Categories

Resources