Drawing multiple cubes at random positions in opengl es android
Asked Answered
P

2

1

Using OpenGL ES I am rendering a simple cube class that draws it at the centre of the screen. However, I want to be able to draw multiple such cubes on the screen at random positions but don't know how to. Here is the my custom surface view that renders the cube as a private class. I haven't included my main ActivityManager since its not the concern.

 public class TouchSurfaceView extends GLSurfaceView  {

private final float TRACKBALL_SCALE_FACTOR=52.0f;
private final float TOUCH_SCALE_FACTOR=100.0f/320;
private MyGLRenderer mRenderer;
private float mPreviousX;
private float mPreviousY;


public TouchSurfaceView(Context context) {
    super(context);
    // TODO Auto-generated constructor stub

        mRenderer=new MyGLRenderer();
        setRenderer(mRenderer);
        setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);

}

    private class MyGLRenderer implements GLSurfaceView.Renderer{

    private MyGLCube mCube;
    public float mAngleX;
    public float mAngleY; 


    public MyGLRenderer(){
        mCube=new MyGLCube();
    }



    @Override
    public void onDrawFrame(GL10 gl) {
        // TODO Auto-generated method stub


        gl.glDisable(GL10.GL_DITHER);
         gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);   

         gl.glMatrixMode(GL10.GL_MODELVIEW);
         gl.glLoadIdentity();
         gl.glClientActiveTexture(DRAWING_CACHE_QUALITY_HIGH);
         // gl.glTranslatef(0, 0, -3.0f);
         gl.glTranslatef(0, 0, -3.0f);
         gl.glRotatef(mAngleX, 0, 1, 0);
         gl.glRotatef(mAngleY, 1, 0, 0);
         mCube.draw(gl);

    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        // TODO Auto-generated method stub
        gl.glViewport(0, 0, width, height);
        float ratio=(float) width/height;
        gl.glMatrixMode(GL10.GL_PROJECTION);
        gl.glLoadIdentity();
        gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        // TODO Auto-generated method stub
        gl.glDisable(GL10.GL_DITHER);
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
        gl.glClearColor(0.5f, 2, 0.63f, 0.2f);

    }


}
 }

Here is MYGLCube that contains vertices, indices and other stuff for constructing the cube

    public class MyGLCube {


private float vertices[]={
        0.3f,0.3f,-0.3f, // topFront Right
        0.3f,-0.3f,-0.3f, //BottomFront Right
       -0.3f,-0.3f,-0.3f, //BottomFront Left
       -0.3f,0.3f,-0.3f,  //topFront Left
       0.3f,0.3f,0.3f, // topBack Right
       0.3f,-0.3f,0.3f, //BottomBack Right
       -0.3f,-0.3f,0.3f, //BottomBack Left
       -0.3f,0.3f,0.3f,  //topBack Left
 }; 

private float rgbaVals[]={
        1,1,0,.5f,   // topFront Right color
        0.25f,0, 0.8f,1, //BottomFront Right color
        0,1,1,1, //BottomFront Left color
        0.35f,0.26f,1,0.5f,  //topFront Left color
        0.23f,0.62f,3,0.2f,  // topBack Right color
        0.3f,0.43f,1,0.2f,  //BottomBack Right color
        0.2f, 0.3f, 0.73f,0.6f,  //BottomBack Left color
        0.6f, 0.9f, 0.65f, 0.2f //topBack Left color            
};

private short pIndex[]={
          3,4,0,  0,4,1,   3,0,1, 
          3,7,4,   7,6,4,  7,3,6,
          3,1,2,   1,6,2,  6,3,2,
          1,4,5,   5,6,1,  6,5,4            
};
private FloatBuffer vertBuff, cBuff;
private ShortBuffer pBuff;


public MyGLCube(){
  ByteBuffer bBuff=ByteBuffer.allocateDirect(vertices.length*4);    
  bBuff.order(ByteOrder.nativeOrder());
  vertBuff=bBuff.asFloatBuffer();
  vertBuff.put(vertices);
  vertBuff.position(0);

  ByteBuffer pbBuff=ByteBuffer.allocateDirect(pIndex.length*2);
  pbBuff.order(ByteOrder.nativeOrder());
  pBuff=pbBuff.asShortBuffer();
  pBuff.put(pIndex);
  pBuff.position(0);

  ByteBuffer colorBuff=ByteBuffer.allocateDirect(rgbaVals.length*4);
  colorBuff.order(ByteOrder.nativeOrder());
  cBuff=colorBuff.asFloatBuffer();
  cBuff.put(rgbaVals);
  cBuff.position(0);


}

public void draw(GL10 gl){
    gl.glFrontFace(GL10.GL_CW);
    gl.glEnable(GL10.GL_CULL_FACE);
    gl.glEnable(GL10.GL_SMOOTH);
    gl.glEnable(GL10.GL_DEPTH_TEST);
    gl.glCullFace(GL10.GL_BACK);
    gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
    gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertBuff);
    gl.glColorPointer(4, GL10.GL_FLOAT, 0, cBuff);
    gl.glDrawElements(GL10.GL_TRIANGLES, pIndex.length, GL10.GL_UNSIGNED_SHORT, pBuff);
    gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
    gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
    gl.glDisable(GL10.GL_CULL_FACE);
 }  



}
Pursuant answered 26/3, 2012 at 20:21 Comment(0)
B
4

You must use glPushMatrix and glPopMatrix to return to previus possition after translate,rotate...

@Override
public void onDrawFrame(GL10 gl) {
    // TODO Auto-generated method stub


    gl.glDisable(GL10.GL_DITHER);
     gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);   

     gl.glMatrixMode(GL10.GL_MODELVIEW);
     gl.glLoadIdentity();
     gl.glClientActiveTexture(DRAWING_CACHE_QUALITY_HIGH);

     //Draw cube 1
     gl.glPushMatrix();
     gl.glTranslatef(-0.5f, 0, -3.0f);
     gl.glRotatef(mAngleX, 0, 1, 0);
     gl.glRotatef(mAngleY, 1, 0, 0);
     mCube.draw(gl);
     gl.glPopMatrix();

     //Draw cube 2
     gl.glPushMatrix();
     gl.glTranslatef(0, 0, -3.0f); 
     gl.glRotatef(mAngleX, 0, 1, 0);
     gl.glRotatef(mAngleY, 1, 0, 0);
     mCube.draw(gl);
     gl.glPopMatrix();

     //Draw cube 3
     gl.glPushMatrix();
     gl.glTranslatef(0.5f, 0, -3.0f); 
     gl.glRotatef(mAngleX, 0, 1, 0);
     gl.glRotatef(mAngleY, 1, 0, 0);
     mCube.draw(gl);
     gl.glPopMatrix();

}
Bauhaus answered 27/3, 2012 at 12:39 Comment(3)
I got nothing drawn. I had to remove the gl.PopMatrix() after the last cube drawing. Should it work without removing too?Flatto
@Mitulátbáti ,the number of gl.PopMatrix() calls should be the same as glPushMatrix() , search if somewhere in your code you have a pushmatrix without its proper popmatrixBauhaus
Generating 1000 cubes and it works. But with these 3, it still doesn't work when there are 3-3 pop/pushmatrix. I don't understand why... thanks anyway.Flatto
S
1

The code you have that actually draws the cube are these three lines:

gl.glTranslatef(0, 0, -3.0f);
gl.glRotatef(mAngleX, 0, 1, 0);
gl.glRotatef(mAngleY, 1, 0, 0);
mCube.draw(gl);

It moved the coordinate system, then rotates it and then draws the cube. What you want to do it move it somewhere else and draw the cube there. Like this:

gl.glTranslatef(1.0, 0, 0f);
mCube.draw(gl);
Stegman answered 26/3, 2012 at 20:30 Comment(3)
Thanks. Move it somewhere else? Like how? Lets put it simple. How can I draw a 2nd cube in my code at a position different from the current?Pursuant
that didn't work. It either didn't draw or moved the cube somewhere off-screen. Moreover, it still quite doesn't address the main concern of the question. I want to be able to draw multiple such cubes from the same class. Positions can be the 2nd concern.Pursuant
It's possible that it moved the cube off of the screen. I don't know how you've set up your projection. What you need to do is learn OpenGL. Here is a great resource for that: nehe.gamedev.net OpenGL is an extremely low level API. If you're looking for something higher level have a look at Unity.Stegman

© 2022 - 2024 — McMap. All rights reserved.