Обновление вида после применения поворота на одном 3D-объекте OpenGL ES 2.0 - PullRequest
0 голосов
/ 30 апреля 2018

Я работал над приложением, основанным на образце ARCore для Android Studio. Мне удалось вывести на экран разные объекты по моему выбору, и теперь я пытаюсь повернуть только один объект, который является последним помещенным объектом. Это означает, что при выборе объекта я должен иметь возможность вращать его и изменять его положение, пока я не выберу другой объект. Чем я больше не смогу манипулировать этим объектом. Теперь это мой метод draw (), который вызывается для каждого размещенного объекта

public void draw(float[] cameraView, float[] cameraPerspective, float lightIntensity) {

    ShaderUtil.checkGLError(TAG, "Before draw");

    // Build the ModelView and ModelViewProjection matrices
    // for calculating object position and light.
    Matrix.multiplyMM(modelViewMatrix, 0, cameraView, 0, modelMatrix, 0);
    Matrix.multiplyMM(modelViewProjectionMatrix, 0, cameraPerspective, 0, modelViewMatrix, 0);



    if(this.movable==true) {
      //rotation
      Matrix.setRotateM(mRotationMatrix, 0, FactorsClass.rotateF, 0.0f, 1.0f, 0.0f);
      Matrix.multiplyMM(mFinalModelViewProjectionMatrix, 0, modelViewProjectionMatrix, 0, mRotationMatrix, 0);
    }

    GLES20.glUseProgram(program);

    // Set the lighting environment properties.
    Matrix.multiplyMV(viewLightDirection, 0, modelViewMatrix, 0, LIGHT_DIRECTION, 0);
    normalizeVec3(viewLightDirection);
    GLES20.glUniform4f(
        lightingParametersUniform,
        viewLightDirection[0],
        viewLightDirection[1],
        viewLightDirection[2],
        lightIntensity);

    // Set the object material properties.
    GLES20.glUniform4f(materialParametersUniform, ambient, diffuse, specular, specularPower);

    // Attach the object texture.
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textures[0]);
    GLES20.glUniform1i(textureUniform, 0);

    // Set the vertex attributes.
    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vertexBufferId);

    GLES20.glVertexAttribPointer(
        positionAttribute, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, 0, verticesBaseAddress);
    GLES20.glVertexAttribPointer(normalAttribute, 3, GLES20.GL_FLOAT, false, 0, normalsBaseAddress);
    GLES20.glVertexAttribPointer(
        texCoordAttribute, 2, GLES20.GL_FLOAT, false, 0, texCoordsBaseAddress);

    GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);

    // Set the ModelViewProjection matrix in the shader.
    GLES20.glUniformMatrix4fv(modelViewUniform, 1, false, modelViewMatrix, 0);


      GLES20.glUniformMatrix4fv(modelViewProjectionUniform, 1, false, modelViewProjectionMatrix, 0);
      if(this.movable==true) {
        GLES20.glUniformMatrix4fv(modelViewProjectionUniform, 1, false, mFinalModelViewProjectionMatrix, 0);
      }


    // Enable vertex arrays
    GLES20.glEnableVertexAttribArray(positionAttribute);
    GLES20.glEnableVertexAttribArray(normalAttribute);
    GLES20.glEnableVertexAttribArray(texCoordAttribute);

    if (blendMode != null) {
      GLES20.glDepthMask(false);
      GLES20.glEnable(GLES20.GL_BLEND);
      switch (blendMode) {
        case Shadow:
          // Multiplicative blending function for Shadow.
          GLES20.glBlendFunc(GLES20.GL_ZERO, GLES20.GL_ONE_MINUS_SRC_ALPHA);
          break;
        case Grid:
          // Grid, additive blending function.
          GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
          break;
      }
    }

    GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, indexBufferId);
    GLES20.glDrawElements(GLES20.GL_TRIANGLES, indexCount, GLES20.GL_UNSIGNED_SHORT, 0);
    GLES20.glBindBuffer(GLES20.GL_ELEMENT_ARRAY_BUFFER, 0);

    if (blendMode != null) {
      GLES20.glDisable(GLES20.GL_BLEND);
      GLES20.glDepthMask(true);
    }

    // Disable vertex arrays
    GLES20.glDisableVertexAttribArray(positionAttribute);
    GLES20.glDisableVertexAttribArray(normalAttribute);
    GLES20.glDisableVertexAttribArray(texCoordAttribute);

    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, 0);

    ShaderUtil.checkGLError(TAG, "After draw");
  }

В данный момент я могу вращать объект по своему желанию (когда переменная подвижна - true, что означает, что это последний объект, помещенный в сцену), но как только я выберу другой объект, старый объект вернется к своему первоначальному положение, как будто оно никогда не вращалось. Как я могу обновить матрицу, чтобы повороты оставались примененными? Спасибо!

1 Ответ

0 голосов
/ 30 апреля 2018

но как только я выбираю другой, старый объект возвращается в исходное положение, как будто он никогда не вращался. Как я могу обновить матрицу, чтобы повороты оставались в силе?

Я предполагаю, что mRotationMatrix является членом класса. Убедитесь, что mRotationMatrix инициализируется матрицей идентификаторов.

Обновить mRotationMatrix, если this.movable==true, но использовать mRotationMatrix в любом случае для вычисления mFinalModelViewProjectionMatrix. В любом случае используйте mFinalModelViewProjectionMatrix для установки modelViewProjectionUniform.

public void draw(float[] cameraView, float[] cameraPerspective, float lightIntensity) {

    .....

    Matrix.multiplyMM(modelViewMatrix, 0, cameraView, 0, modelMatrix, 0);
    Matrix.multiplyMM(modelViewProjectionMatrix, 0, cameraPerspective, 0, modelViewMatrix, 0);


    if(this.movable==true) {
        Matrix.setRotateM(mRotationMatrix, 0, FactorsClass.rotateF, 0.0f, 1.0f, 0.0f);
    }
    Matrix.multiplyMM(mFinalModelViewProjectionMatrix, 0, modelViewProjectionMatrix, 0, mRotationMatrix, 0);

    .....

    GLES20.glUniformMatrix4fv(modelViewProjectionUniform, 1, false, mFinalModelViewProjectionMatrix, 0);

    .....
}
...