2014-02-10 4 views
3

Im new to OpenGL и началось с небольшого урока с сайта dev.android.com. код примера включает этот квадратный класс для квадратной геометрии. Объект будет создан в методе 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(), но после касания события?

Я попытался определить квадратную переменную, но не инициализировать ее на onSurfaceCreated(), а затем проверить, является ли объект нулевым до его рисования. После прикосновения я назвал

mSquare = new Square(); 

Я знаю его не очень хороший способ реализации этого, но я просто хотел попробовать, если это работает. Я бы создал список доступных элементов и пропустил его в методе onDrawFrame(), вызывая каждый draw() из объектов списка. Но так как этот метод приводит к сбою Proram, я не знаю, как идти дальше

ответ

3

Вы можете делать только вызовы OpenGL в контексте OpenGL.

Есть 3 способа, в которых этот контекст существует:

1) onSurfaceCreated - когда conext это созидатель/воссозданы - вы должны загрузить ресурсы здесь

2) onSurfaceChanged - после создания и на поверхности изменения размера - вы должны назначать переменные, зависящие от размера, здесь

3) - здесь выполняется рендеринг. Здесь вы должны выполнить все команды рисования

При попытке выполнить OpenGL вызовов вне контекста - скорее всего, код не сможет правильно

+0

спасибо за быстрый ответ так было бы хорошим решением, чтобы изменить, например, логическое значение с touch, так что метод 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; 
} 
Смежные вопросы