2014-02-10 112 views
3

Im新的OpenGL,並從dev.android.com的小教程開始。示例代碼包含這個方形幾何的Square類。該對象將在onSurfaceCreated()方法中創建,並使用onDrawFrame()繪製每個幀。這裏是廣場(構造函數和抽取方法)的示例代碼:OpenGL ES在運行時創建對象

public Square() { 
    // initialize vertex byte buffer for shape coordinates 

    ByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length * 4); 
    bb.order(ByteOrder.nativeOrder()); 
    vertexBuffer = bb.asFloatBuffer(); 
    vertexBuffer.put(squareCoords); 
    vertexBuffer.position(0); 

    // initialize byte buffer for the draw list 
    ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * 2); 
    dlb.order(ByteOrder.nativeOrder()); 
    drawListBuffer = dlb.asShortBuffer(); 
    drawListBuffer.put(drawOrder); 
    drawListBuffer.position(0); 

    // prepare shaders and OpenGL program 
    int vertexShader = MyGLRenderer.loadShader(
      GLES20.GL_VERTEX_SHADER, 
      vertexShaderCode); 

    int fragmentShader = MyGLRenderer.loadShader(
      GLES20.GL_FRAGMENT_SHADER, 
      fragmentShaderCode); 

    mProgram = GLES20.glCreateProgram();    // create empty OpenGL Program 
    GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program 
    GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program 
    GLES20.glLinkProgram(mProgram);     // create OpenGL program executables 
} 


public void draw(float[] mvpMatrix) { 
    // Add program to OpenGL environment 
    GLES20.glUseProgram(mProgram); 

    // get handle to vertex shader's vPosition member 
    mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition"); 

    // Enable a handle to the triangle vertices 
    GLES20.glEnableVertexAttribArray(mPositionHandle); 

    // Prepare the triangle coordinate data 
    GLES20.glVertexAttribPointer(
      mPositionHandle, COORDS_PER_VERTEX, 
      GLES20.GL_FLOAT, false, 
      vertexStride, vertexBuffer); 

    // get handle to fragment shader's vColor member 
    mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor"); 

    // Set color for drawing the triangle 
    GLES20.glUniform4fv(mColorHandle, 1, color, 0); 

    // get handle to shape's transformation matrix 
    mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); 
    MyGLRenderer.checkGlError("glGetUniformLocation"); 

    // Apply the projection and view transformation 
    GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0); 
    MyGLRenderer.checkGlError("glUniformMatrix4fv"); 

    // Draw the square 
    GLES20.glDrawElements(
      GLES20.GL_TRIANGLES, drawOrder.length, 
      GLES20.GL_UNSIGNED_SHORT, drawListBuffer); 

    // Disable vertex array 
    GLES20.glDisableVertexAttribArray(mPositionHandle); 
} 

我的問題是現在:我怎樣才能創建對象不是onSurfaceCreated(),但觸摸事件之後?

我試圖定義一個Square變量,但不是在onSurfaceCreated()上初始化它,然後在繪製它之前檢查對象是否爲null。觸摸後,我叫

mSquare = new Square(); 

我知道它不是實現這個的一個好辦法,但我只是想嘗試是否可行。我將創建一個可繪製元素列表,並在onDrawFrame()方法中通過它執行,從列表對象中調用每個draw()。但由於這種方法導致Proram崩潰,我不知道如何繼續

回答

3

您只能在OpenGL上下文中調用OpenGL。

有3種方法在這種情況下存在:

1)onSurfaceCreated - 當conext是創世/重現 - 後創作和表面調整大小 - - 你應該onSurfaceChanged加載此資源

2)你應在這裏分配尺寸相關變量

3) - 此處執行渲染。在這裏,你應該執行的所有繪畫命令

如果您嘗試執行OpenGL調用上下文之外 - 最有可能的代碼將無法正確

+0

感謝您的快速答覆 所以會是一個很好的解決方案,以改變例如用一個布爾觸摸事件,以便onDrawFrame方法創建對象? – user3183627

+0

如果您在onDrawFrame之前預先加載您將使用的所有對象,那麼最好。在onTouchEvent中,您可能會更改一些參數(例如要顯示的對象和位置),並在onDrawFrame中使用此參數進行呈現 – Sam

0

Android和GL上下文是不同的執行,他們在不同的運行(管理)的線程用自己的方式 所以如果你想創建您所創建的對象的觸摸一個正方形,你必須這樣做,在GLcontext這樣

  1. http://pastebin.com/zAav7jpu

  2. 初始化您的對象在觸摸/或您想要做的事

    public static isAddedBody = false; //在touch_class中全局聲明 public void touch(int .. whateva)mSquare = new Square(); isAddedBody = true;

    }

在渲染()/或繪製()循環

if (touch_class.isAddedBody){ 
    mSquare.createBody(); 
    touch_class.isAdded = false; 
}