OpenGLES-在运行时创建对象

use*_*627 4 java android opengl-es opengl-es-2.0

我是OpenGL的新手,从dev.android.com的小教程开始。示例代码包括Square用于正方形几何的此类。该对象将在onSurfaceCreated()方法中创建,并使用绘制每一帧onDrawFrame()。这是Square(构造函数和绘制方法)的示例代码:

   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);
}
Run Code Online (Sandbox Code Playgroud)

现在的问题是:如何在onSurfaceCreated()触摸事件发生后而不是在创建对象?

我尝试定义一个Square变量,但未在对其进行初始化onSurfaceCreated(),然后在绘制该对象之前检查该对象是否为null。触摸后,我打电话给:

mSquare = new Square();
Run Code Online (Sandbox Code Playgroud)

我知道这不是实现此目标的好方法,但我只是想尝试一下是否可行。我将创建一个可绘制元素的列表,并在onDrawFrame()方法中运行它,并draw()从列表对象中调用每个元素。但是由于此方法导致程序崩溃,所以我不知道如何继续。

Sam*_*Sam 5

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

存在此上下文的3种方法:

1)onSurfaceCreated-创建/重新创建上下文时-您应在此处加载资源

2)onSurfaceChanged-创建后并调整表面大小-您应在此处分配与尺寸有关的变量

3)onDrawFrame-在这里执行渲染-在这里您应该执行所有绘图命令

如果您尝试在上下文之外执行OpenGL调用,则很可能代码将无法正确执行。