2012-03-15 3 views
1

그래서 나는 구글이 튜토리얼을 따라 회전하지 않습니다 http://developer.android.com/resources/tutorials/opengl/opengl-es20.html삼각형

이 삼각형이 터치 이벤트에 대한 응답으로 회전하도록되어, 그러나 아무 일도 발생하지 않습니다. 그것은 또한 스스로 회전 할 때 이전 단계에서 회전하지 않았습니다. 문제가 무엇인지 잘 모릅니다. 방금 코드를 복사했습니다.

전체 프로젝트는 두 개의 파일입니다 :

HelloOpenGLES20Activity.java

package com.opengl.es20; 

import android.app.Activity; 
import android.content.Context; 
import android.opengl.GLSurfaceView; 
import android.os.Bundle; 
import android.view.MotionEvent; 

public class HelloOpenGLES20Activity extends Activity { 

    private GLSurfaceView mGLView; 

    @Override 
    public void onCreate(Bundle savedInstanceState) { 
     super.onCreate(savedInstanceState); 

     // Create a GLSurfaceView instance and set it 
     // as the ContentView for this Activity 
     mGLView = new HelloOpenGLES20SurfaceView(this); 
     setContentView(mGLView); 
    } 

    @Override 
    protected void onPause() { 
     super.onPause(); 
     // The following call pauses the rendering thread. 
     // If your OpenGL application is memory intensive, 
     // you should consider de-allocating objects that 
     // consume significant memory here. 
     mGLView.onPause(); 
    } 

    @Override 
    protected void onResume() { 
     super.onResume(); 
     // The following call resumes a paused rendering thread. 
     // If you de-allocated graphic objects for onPause() 
     // this is a good place to re-allocate them. 
     mGLView.onResume(); 
    } 
} 

class HelloOpenGLES20SurfaceView extends GLSurfaceView { 

    private final float TOUCH_SCALE_FACTOR = 180.0f/320; 
    private HelloOpenGLES20Renderer mRenderer; 
    private float mPreviousX; 
    private float mPreviousY; 

    public HelloOpenGLES20SurfaceView(Context context){ 
     super(context); 

     // Create an OpenGL ES 2.0 context. 
     setEGLContextClientVersion(2); 
     // set the mRenderer member 
     mRenderer = new HelloOpenGLES20Renderer(); 
     setRenderer(mRenderer); 

     // Render the view only when there is a change 
     setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY); 

    } 

    @Override 
    public boolean onTouchEvent(MotionEvent e) { 
     // MotionEvent reports input details from the touch screen 
     // and other input controls. In this case, you are only 
     // interested in events where the touch position changed. 

     float x = e.getX(); 
     float y = e.getY(); 

     switch (e.getAction()) { 
      case MotionEvent.ACTION_MOVE: 

       float dx = x - mPreviousX; 
       float dy = y - mPreviousY; 

       // reverse direction of rotation above the mid-line 
       if (y > getHeight()/2) { 
        dx = dx * -1 ; 
       } 

       // reverse direction of rotation to left of the mid-line 
       if (x < getWidth()/2) { 
        dy = dy * -1 ; 
       } 

       mRenderer.mAngle += (dx + dy) * TOUCH_SCALE_FACTOR; 
       requestRender(); 
     } 

     mPreviousX = x; 
     mPreviousY = y; 
     return true; 
    } 
} 

HelloRendererOpenGLES20Renderer.java

package com.opengl.es20; 

import java.nio.ByteBuffer; 
import java.nio.ByteOrder; 
import java.nio.FloatBuffer; 

import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.opengles.GL10; 

import android.opengl.GLES20; 
import android.opengl.GLSurfaceView; 
import android.opengl.Matrix; 
import android.os.SystemClock; 

public class HelloOpenGLES20Renderer implements GLSurfaceView.Renderer { 

    private FloatBuffer triangleVB; 
    private final String vertexShaderCode = 
      "uniform mat4 uMVPMatrix; \n" + 
      "attribute vec4 vPosition; \n" + 
      "void main(){    \n" + 
      " gl_Position = uMVPMatrix * vPosition; \n" + 
      "}       \n"; 

    private final String fragmentShaderCode = 
      "precision mediump float; \n" + 
        "void main(){    \n" + 
        " gl_FragColor = vec4 (0.63671875, 0.76953125, 0.22265625, 1.0); \n" + 
        "}       \n"; 
    private int mProgram; 
    private int maPositionHandle; 
    private int muMVPMatrixHandle; 
    private float[] mMVPMatrix = new float[16]; 
    private float[] mMMatrix = new float[16]; 
    private float[] mVMatrix = new float[16]; 
    private float[] mProjMatrix = new float[16]; 

    public float mAngle; 

    public void onSurfaceCreated(GL10 unused, EGLConfig config) { 
     int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexShaderCode); 
     int fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentShaderCode); 
     // Set the background frame color 
     GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); 
     initShapes(); 

     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);     // creates OpenGL program executables 

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

    public void onDrawFrame(GL10 unused) { 

     // Redraw background color 
     GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 
     // Add program to OpenGL environment 
     GLES20.glUseProgram(mProgram); 

     // Prepare the triangle data 
     GLES20.glVertexAttribPointer(maPositionHandle, 3, GLES20.GL_FLOAT, false, 12, triangleVB); 
     GLES20.glEnableVertexAttribArray(maPositionHandle); 

     // Create a rotation for the triangle 
//  long time = SystemClock.uptimeMillis() % 4000L; 
//  float angle = 0.090f * ((int) time); 
     Matrix.setRotateM(mMMatrix, 0, mAngle, 0, 0, 1.0f); 
     Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0); 
     Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0); 

     // Apply a ModelView Projection transformation 
     Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0); 
     GLES20.glUniformMatrix4fv(muMVPMatrixHandle, 1, false, mMVPMatrix, 0); 

     // Draw the triangle 
     GLES20.glDrawArrays(GLES20.GL_TRIANGLES, 0, 3); 
    } 

    public void onSurfaceChanged(GL10 unused, int width, int height) { 
     GLES20.glViewport(0, 0, width, height); 
     float ratio = (float) width/height; 
     Matrix.frustumM(mProjMatrix, 0, -ratio, ratio, -1, 1, 3, 7); 
     muMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix"); 
     Matrix.setLookAtM(mVMatrix, 0, 0, 0, -3, 0f, 0f, 0f, 0f, 1.0f, 0.0f); 
    } 

    private void initShapes(){ 

     float triangleCoords[] = { 
      // X, Y, Z 
      -0.5f, -0.25f, 0, 
      0.5f, -0.25f, 0, 
      0.0f, 0.559016994f, 0 
     }; 

     // initialize vertex Buffer for triangle 
     ByteBuffer vbb = ByteBuffer.allocateDirect(
       // (# of coordinate values * 4 bytes per float) 
       triangleCoords.length * 4); 
     vbb.order(ByteOrder.nativeOrder());// use the device hardware's native byte order 
     triangleVB = vbb.asFloatBuffer(); // create a floating point buffer from the ByteBuffer 
     triangleVB.put(triangleCoords); // add the coordinates to the FloatBuffer 
     triangleVB.position(0);   // set the buffer to read the first coordinate 

    } 

    private int loadShader(int type, String shaderCode){ 

     // create a vertex shader type (GLES20.GL_VERTEX_SHADER) 
     // or a fragment shader type (GLES20.GL_FRAGMENT_SHADER) 
     int shader = GLES20.glCreateShader(type); 

     // add the source code to the shader and compile it 
     GLES20.glShaderSource(shader, shaderCode); 
     GLES20.glCompileShader(shader); 

     return shader; 
    } 

} 

답변

2
Matrix.setRotateM(mMMatrix, 0, mAngle, 0, 0, 1.0f); 
    Matrix.multiplyMM(mMVPMatrix, 0, mVMatrix, 0, mMMatrix, 0); 
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mMVPMatrix, 0); 

    // Apply a ModelView Projection transformation 
    Matrix.multiplyMM(mMVPMatrix, 0, mProjMatrix, 0, mVMatrix, 0); 

나는 마지막 multiplyMM이 문제 믿습니다. mMVPMatrix를 mMVPMatrix = mProjMatrix * mVMatrix로 재설정하면 회전을 적용 할 모델 변형 행렬 mMMatrix가 손실됩니다. 또한, mAngle이 0이 아닌지 확인하십시오.

+0

마지막 multiplyMM을 주석 처리하고 작동합니다! 감사! – Legion