2014-01-22 61 views
0

我開始使用Android中的OpenGL ES,並且遇到了一個我不太明白的情況。 OpenGL的原點應該是屏幕的左下角,對嗎?因爲對我來說,它似乎在屏幕中間。到目前爲止,我只是通過翻譯和旋轉到我想要的座標系來解決這個問題,但我想首先理解爲什麼會發生這種情況。下面,這是一個最小的例子,它將精靈放置在屏幕的死點。我沒有在此代碼中執行任何翻譯或旋轉。OpenGL中原點的位置

package com.lyrismobilestudio.opengltest; 

import android.app.Activity; 
import android.content.Context; 
import android.graphics.Bitmap; 
import android.graphics.BitmapFactory; 
import android.opengl.GLUtils; 
import android.opengl.GLSurfaceView; 
import android.opengl.GLSurfaceView.Renderer; 
import android.os.Bundle; 
import java.io.InputStream; 
import java.nio.ByteBuffer; 
import java.nio.FloatBuffer; 
import java.nio.ByteOrder; 
import javax.microedition.khronos.opengles.GL10; 
import javax.microedition.khronos.egl.EGLConfig; 

public class MainActivity extends Activity { 
    @Override protected void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     GLSurfaceView view = new GLSurfaceView(this); 
     Renderer renderer = new MyRenderer(this); 
     view.setRenderer(renderer); 
     setContentView(view); 
    } 
} 

class MyRenderer implements Renderer { 
    public Sprite strike; 
    public Context context; 

    public MyRenderer(Context context) { 
     this.context = context; 
     strike = new Sprite(); 
    } 

    @Override public void onDrawFrame(GL10 gl) { 
     gl.glClearColor(.5f,.5f,1f,0f); 
     gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); 
     strike.draw(gl); 
     try { Thread.sleep(100); } catch (Exception e) {} 
    } 

    @Override public void onSurfaceChanged(GL10 gl, int width, int height){ 
    } 

    @Override public void onSurfaceCreated(GL10 gl, EGLConfig arg1) { 
     strike.loadTexture(gl, R.drawable.strike, context); 
    } 
} 

class Sprite { 
    FloatBuffer vertexBuffer; 
    FloatBuffer textureBuffer; 
    ByteBuffer indexBuffer; 
    private int[] textures = new int[1]; 

    public Sprite() { 
     float[] vertices = { 
      -.1f, .1f, 
      .1f, .1f, 
      .1f, -.1f, 
      -.1f, -.1f, 
     }; 
     float[] textureVertices = new float[]{ 
      0f, 0f, 
      1f, 0f, 
      1f, 1f, 
      0f, 1f 
     }; 
     byte indices[] = { 
      0, 1, 2, 
      0, 2, 3 
     }; 
     ByteBuffer temp = ByteBuffer.allocateDirect(vertices.length*4); 
     temp.order(ByteOrder.nativeOrder()); 
     vertexBuffer = temp.asFloatBuffer(); 
     vertexBuffer.put(vertices); 
     vertexBuffer.position(0); 
     temp = ByteBuffer.allocateDirect(textureVertices.length*4); 
     temp.order(ByteOrder.nativeOrder()); 
     textureBuffer = temp.asFloatBuffer(); 
     textureBuffer.put(textureVertices); 
     textureBuffer.position(0); 
     indexBuffer = ByteBuffer.allocateDirect(indices.length); 
     indexBuffer.put(indices); 
     indexBuffer.position(0); 
    } 

    public void draw(GL10 gl){ 
     gl.glVertexPointer(2, GL10.GL_FLOAT, 0, vertexBuffer); 
     gl.glEnableClientState(GL10.GL_VERTEX_ARRAY); 

     gl.glEnable(GL10.GL_TEXTURE_2D); 
     gl.glEnable(GL10.GL_BLEND); 
     gl.glBlendFunc(GL10.GL_SRC_ALPHA,GL10.GL_ONE_MINUS_SRC_ALPHA); 
     gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]); 
     gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer); 
     gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 

     gl.glDrawElements(GL10.GL_TRIANGLES, 6, GL10.GL_UNSIGNED_BYTE, indexBuffer); 
     gl.glDisableClientState(GL10.GL_VERTEX_ARRAY); 
     gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY); 
    } 

    public void loadTexture(GL10 gl, int texture, Context context){ 
     InputStream imageStream = context.getResources().openRawResource(texture); 
     Bitmap bitmap = null; 
     try { 
      bitmap = BitmapFactory.decodeStream(imageStream); 
     } catch (Exception e) { 
     } finally { 
      try { 
       imageStream.close(); 
       imageStream=null; 
      } catch (Exception e) { 
      } 
     } 
     gl.glGenTextures(1, textures, 0); 
     gl.glBindTexture(GL10.GL_TEXTURE_2D,textures[0]); 
     gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST); 
     gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_LINEAR); 
     GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0); 
     bitmap.recycle(); 
    } 
} 
+0

視口座標來自x和y的[-1,1] –

回答

0

默認情況下,OpenGL在屏幕上使用一個視口,該視口涵蓋x軸和y軸的座標範圍-1到+1。因此,原點位於屏幕的中心。請注意,因爲x和y的座標範圍相同,所以對象將顯得拉伸(除非您的屏幕是方形的......)。一個很好的例子可以在這裏找到:http://developer.android.com/guide/topics/graphics/opengl.html

爲了迎合你的屏幕的幾何(以及查看繪製在-1/+ 1範圍之外的對象),你需要引入一個投影矩陣。然後你需要一個相機轉換矩陣,它定義了你的座標空間在哪裏,以及在哪個方向上。

+0

那麼,那是預期的行爲?我可以接受。我讀過的所有書都說它會在左下角,但如果不是這樣的話,我還可以。我只是想確保我沒有搞砸任何事情。謝謝! – Jeremy

0

原點位於屏幕的中心。 X指向右側,Y指向上方,Z指向屏幕外。由於您沒有更改投影矩陣,因此它在每個方向上從-1變爲1。