2011-04-17 64 views
0

經過大量的試驗和錯誤之後,我能夠爲多維數據集繪製立方體和瓷磚地圖。我添加了輸入,以便在移動手指時相機移動。但現在我想在我的遊戲進程中添加下一步。我希望它讓我的立方體移動到我在三維空間按下我的手指的位置。這聽起來有點困難。我想要做的是用一根手指在地圖上滑動相機,另一隻手指則雙擊並移動。到目前爲止,我的魔方抖動並擺動到位,但不會移動到我想要的位置。當然,我的代碼中沒有一個是完美的,我的下面的gluunproject可能遠不是正確的。這是到目前爲止我的代碼在android的幫助下在opengl中移動多維數據集

多維數據集的創建者和更新代碼//其短

public shapemaker(int x, int y, int z,int width) 
{ 
    centerx =x; 
    centery =y; 
    centerz =z; 



     mysquare1= new square(centerx,centery,centerz-5,1,.0f,.0f,1f,"vert"); 
     mysquare2= new square(centerx-1,centery,centerz-6f,1,.0f,1.0f,.0f,"side"); 
     mysquare3= new square(centerx,centery,centerz-7,1,1.0f,.0f,.0f,"vert"); 
     mysquare4= new square(centerx+1,centery,centerz-6f,1,.0f,.5f,.5f,"side"); 
     mysquare5= new square(centerx,centery-1,centerz-6f,1,.5f,.5f,.0f,"horiz"); 
     mysquare6= new square(centerx,centery+1,centerz-6f,1,.5f,.0f,.5f,"horiz"); 
} 

public void updatecube(float x, float y, float z) 
{ 


     centerx =x; 
     centery =y; 
     centerz =z; 

     mysquare1= new square(centerx,centery,centerz-5,1,.0f,.0f,1f,"vert"); 
     mysquare2= new square(centerx-1,centery,centerz-6f,1,.0f,1.0f,.0f,"side"); 
     mysquare3= new square(centerx,centery,centerz-7,1,1.0f,.0f,.0f,"vert"); 
     mysquare4= new square(centerx+1,centery,centerz-6f,1,.0f,.5f,.5f,"side"); 
     mysquare5= new square(centerx,centery-1,centerz-6f,1,.5f,.5f,.0f,"horiz"); 
     mysquare6= new square(centerx,centery+1,centerz-6f,1,.5f,.0f,.5f,"horiz"); 
} 

public void drawcube(GL10 gl) 
{ 
    mysquare1.draw(gl);   
    mysquare2.draw(gl);   
    mysquare3.draw(gl);   
    mysquare4.draw(gl);   
    mysquare5.draw(gl);   
    mysquare6.draw(gl); 

} 
public float getcenterx() 
{ 
    return centerx; 
} 
public float getcentery() 
{ 
    return centery; 
} 
public float getcenterz() 
{ 
    return centerz; 
} 

下面是實際的實現代碼,它是基於谷歌關閉前奏的OpenGL的

class ClearGLSurfaceView extends GLSurfaceView { 
    private static final String BufferUtils = null; 
    float x =0; 
    float y =0; 
    float z =0f; 
    float prevx=0; 
    float prevy=0; 
    GL10 mygl; 
    // GL gl; 
    float mywidth; 
    float myheight; 








public ClearGLSurfaceView(Context context,float width, float height) { 
    super(context); 
    mRenderer = new ClearRenderer(); 
    setRenderer(mRenderer); 
    mywidth = width; 
    myheight = height; 





} 
@Override 
public boolean onTouchEvent(final MotionEvent event) 
{ 

    queueEvent(new Runnable() { 
     // Find the index of the active pointer and fetch its position 
     public void run() 
     { 
      float curx = event.getX(); 
      float cury = event.getY(); 
      final int action = event.getAction(); 
      if(action == MotionEvent.ACTION_MOVE) 
      { 


      if(curx>prevx) 
      { 
        x-=.1f; 
      } 
      if(curx<prevx) 
      { 
        x+=.1f; 
      } 
      if(cury>prevy) 
      { 
        y+=.1f; 
      } 
      if(cury<prevy) 
      { 
        y-=.1f; 
      } 



      } 
      if(action == MotionEvent.ACTION_DOWN) 
      { 
       // GLU.gluUnProject(winX, winY, winZ, model, 
       //  modelOffset, project, projectOffset, view, viewOffset, obj, objOffset) 
       vector2d moveto = new vector2d(0,0); 
       moveto = mRenderer.getworkcoords(curx,cury); 
       Log.i("move to ", "x "+moveto.x+" y "+ moveto.y+" z " + moveto.z); 
       mRenderer.updatemoveto(moveto.x, moveto.y); 



      } 
      prevx= curx; 
      prevy = cury; 

      mRenderer.updatecamera(x, y, z); 
} 
}); 
    return true; 
} 

    ClearRenderer mRenderer; 

}

類ClearRenderer實現GLSurfaceView.Renderer {

 GL10 mygl; 
     GL11 mygl11; 

     int viewport[] = new int[4]; 
     float modelview[] = new float[16]; 
     float projection[] = new float[16]; 
     float wcoord[] = new float[4]; 

public void onSurfaceCreated(GL10 gl, EGLConfig config) { 

    gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // OpenGL docs. 
    gl.glShadeModel(GL10.GL_SMOOTH);// OpenGL docs. 
    gl.glClearDepthf(1.0f);// OpenGL docs. 
    gl.glEnable(GL10.GL_DEPTH_TEST);// OpenGL docs. 
    gl.glDepthFunc(GL10.GL_LEQUAL);// OpenGL docs. 
    gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, // OpenGL docs. 
         GL10.GL_NICEST); 

    mygl = gl; 
    mygl11 = (GL11) gl; 
    int index; 
    int counter = 0; 
    float zcoord = -7.0f; 

    mygl11.glGetFloatv(GL11.GL_MODELVIEW_MATRIX, modelview, 0); 
    mygl11.glGetFloatv(GL11.GL_PROJECTION_MATRIX, projection, 0); 
    mygl11.glGetIntegerv(GL11.GL_VIEWPORT, viewport, 0); 

    for(int x=0;x<11;x++) 
    { 
     for(int y =0;y<10;y++) 
     { 
      index = tilemap1[y][x]; 
      if(index==0) 
      { 
       tiles[counter]=new square(x,y,zcoord,0.5f,1.0f,0.0f,0f,"vert"); 

      } 
      if(index==1) 
      { 
       tiles[counter]=new square(x,y,zcoord,0.5f,0f,1.0f,0f,"vert"); 

      } 
      if(index==2) 
      { 
       tiles[counter]=new square(x,y,zcoord,0.5f,0.0f,0.0f,1f,"vert"); 

      } 
      counter++; 
     } 
    } 


} 

public vector2d getworkcoords(float width,float height) 
{ 
    float[] depth = new float[1]; 
    float winx = width; 
    float winy =viewport[3]-height; 
    //vector2d position = new vector2d(0,0); 
    int test = GLU.gluUnProject(winx, winy,0.0f, modelview, 0, projection, 
      0, viewport, 0, wcoord, 0); 

    vector2d v = new vector2d(0,0); 
    v.x = wcoord[0]; 
    v.y = wcoord[1]; 
    v.z = wcoord[2]; 
    return v ; 
} 

public void onSurfaceChanged(GL10 gl, int w, int h) { 
    gl.glViewport(0, 0, w, h); 

    gl.glMatrixMode(GL10.GL_PROJECTION);// OpenGL docs. 

    gl.glLoadIdentity();// OpenGL docs. 

    GLU.gluPerspective(gl, 45.0f, 
           (float) w/(float) h, 
           0.1f, 100.0f); 

    gl.glMatrixMode(GL10.GL_MODELVIEW);// OpenGL docs. 

    gl.glLoadIdentity();// OpenGL docs. 
} 

public float movetox; 
public float movetoy; 
float currentposx; 
float currentposy; 

public void updatemoveto(float x,float y) { movetox = x; movetoy = y; } 公共無效onDrawFrame(GL10 GL){

gl.glClearColor(mRed, mGreen, mBlue, 1.0f); 
    gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 

    currentposx = mycube.getcenterx(); 
    currentposy = mycube.getcentery(); 

    float x = movetox -currentposx; 
    float y = movetoy - currentposy; 
    double angle = Math.atan2(y, x); 
    double mx =.5f* Math.cos(angle); 
    double my = .5f* Math.sin(angle); 



    double mmx = mx+ currentposx; 
    double mmy = my+ currentposy; 

    mycube.updatecube((float)(mmx), (float)(mmy),0); 


    mycube.drawcube(gl); 

    for(int i = 0;i<110;i++) 
    { 

      tiles[i].draw(gl); 

    } 


} 

public void setColor(float r, float g, float b) { 
    mRed = r; 
    mGreen = g; 
    mBlue = b; 
} 
public void updatecamera(float myx, float myy, float myz) 
{ 

    mygl.glLoadIdentity();// OpenGL docs. 
    GLU.gluLookAt(mygl, myx, myy, myz, myx, myy, myz-10, 0, 1, 0); 

} 


private float mRed; 
private float mGreen; 
private float mBlue; 


int tilemap1[][] = { 
     {0,0,0,0,0,0,0,0,0,0,0}, 
     {0,1,2,1,1,1,1,1,1,1,0}, 
     {0,1,2,1,1,1,1,1,1,1,0}, 
     {0,1,2,1,1,1,1,1,1,1,0}, 
     {0,1,2,2,2,1,1,1,1,1,0}, 
     {0,1,1,1,2,1,1,1,1,1,0}, 
     {0,1,1,1,2,1,1,1,1,1,0}, 
     {0,1,1,1,2,1,1,1,1,1,0}, 
     {0,1,1,1,2,2,1,1,1,1,0}, 
     {0,0,0,0,0,0,0,0,0,0,0}, 
}; 
square[] tiles = new square[110]; 

shapemaker mycube = new shapemaker(0,0,0,1); 

}

我不包括上創建方法和對暫停的。我還需要關於設計代碼結構的建議,因爲我的實現遠非完美。

所以簡而言之。我想幫助搞清楚如何修改我製作的多維數據集移動到我按的位置的代碼。你將如何提高代碼

感謝

回答

0

首先,

你不需要重新對每個移動頂點。這是非常複雜的任務,它會降低幀速率(FPS)。在你的代碼中你有模型矩陣。通常它負責翻譯,縮放模型的旋轉(例如網格,立方體)。在一般情況下,您必須翻譯模型矩陣,然後翻譯多個模型,投影和視圖矩陣,您將獲得設備屏幕的矩陣。然後通過頂點位置和這個矩陣的乘法,你將得到頂點的正確位置。您可以看看這個question/answer