2012-10-03 2 views
6

OpenGL을 사용하여 텍스트를 표시하는 애플리케이션을 만들려고합니다. Matrix.translateM을 사용하여 지정된 개체를 특정 위치로 이동하려고하면 예기치 않은 동작이 발생합니다. 다른 모든 변환 행렬은 예상대로 작동합니다. result imageAndroid OpenGL ES 2.0 : Matrix.traslateM으로 원하는 결과를 얻지 못했습니다.

이 이미지가 변환없이 :

이 내가 Matrix.translateM(model_matrix, 0, -1.0f, 0, 0)를 호출 할 때 내가 무엇을 얻을 enter image description here

이 내 렌더러 코드입니다.

@Override 
public void onSurfaceCreated(GL10 unused, EGLConfig config) { 
    GLES20.glClearColor(0.5f, 0.5f, 0.5f, 1.0f); 
    GLES20.glDisable(GLES20.GL_DEPTH_TEST); 
    GLES20.glEnable(GLES20.GL_BLEND); 
    GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA); 

    // create programs 
    simple_texture = new SimpleTexture(); 

    // create shapes 
    square = new Square(); 

    // create debug text handlers 
    text_fps = new Text(this.font, this.text_scale); 
    text_fps.setSize(50); 
    text_fps.setText("Test\nLonger line"); 

    // set camera position 
    final float eyeX = 0.0f; 
    final float eyeY = 0.0f; 
    final float eyeZ = -3.0f; 

    final float lookX = 0.0f; 
    final float lookY = 0.0f; 
    final float lookZ = 0.0f; 

    final float upX = 0.0f; 
    final float upY = 1.0f; 
    final float upZ = 0.0f; 

    Matrix.setLookAtM(view_matrix, 0, eyeX, eyeY, eyeZ, lookX, lookY, lookZ, upX, upY, upZ); 
} 

@Override 
public void onSurfaceChanged(GL10 unused, int width, int height) { 
    GLES20.glViewport(0, 0, width, height); 

    // set projection matrix 
    float ratio = (float) width/height; 
    Matrix.orthoM(projection_matrix, 0, -ratio, ratio, -1, 1, 3, 7); 

    setScreenRatio(ratio); 
    setScreenHeight(height); 
} 

@Override 
public void onDrawFrame(GL10 unused) { 
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); 

    // calculate projection and view transformation 
    Matrix.multiplyMM(vp_matrix, 0, projection_matrix, 0, view_matrix, 0); 

    // if we are connected to debugger draw statistics 
    drawStatistics(vp_matrix); 
} 

그리고 내 텍스트는 draw입니다.

// use predefined program 
    GLES20.glUseProgram(program); 

    // get attribute positions 
    attr_matrix = GLES20.glGetUniformLocation(program, "u_Matrix"); 
    attr_position = GLES20.glGetAttribLocation(program, "a_Position"); 
    attr_texture_position = GLES20.glGetAttribLocation(program, "a_TexturePosition"); 
    attr_texture = GLES20.glGetUniformLocation(program, "u_Texture"); 

    // set program parameters 
    GLES20.glEnableVertexAttribArray(attr_position); 
    GLES20.glVertexAttribPointer(attr_position, 2, GLES20.GL_FLOAT, false, 2 * 4, square_buffer); 

    // set texture parameters 
    GLES20.glEnableVertexAttribArray(attr_texture_position); 
    GLES20.glVertexAttribPointer(attr_texture_position, 2, GLES20.GL_FLOAT, false, 2 * 4, texture_buffer); 

    // set matrix 
    float[] result = new float[16]; 
    float ratio = (float) texture_height/texture_width; 
    float screen_scale = (float) texture_height/PageRenderer.getScreenHeight(); 

    Matrix.setIdentityM(model_matrix, 0); 
    Matrix.translateM(model_matrix, 0, -1, 0, 0); 
    Matrix.scaleM(model_matrix, 0, screen_scale, screen_scale * ratio, screen_scale); 

    Matrix.setIdentityM(result, 0); 
    Matrix.multiplyMM(result, 0, matrix, 0, model_matrix, 0); 
    GLES20.glUniformMatrix4fv(attr_matrix, 1, false, result, 0); 

    // assign texture 
    GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, index); 
    GLES20.glUniform1i(attr_texture, 0); 

    // perform drawing 
    GLES20.glDrawArrays(GLES20.GL_TRIANGLE_STRIP, 0, 4); 

    // disable vertex array 
    GLES20.glDisableVertexAttribArray(attr_position); 
    GLES20.glDisableVertexAttribArray(attr_texture_position); 

쉐이더 :

int vertex_shader = PageRenderer.loadShader(
      GLES20.GL_VERTEX_SHADER, 
      "uniform mat4 u_Matrix;" + 
      "attribute vec4 a_Position;" + 
      "attribute vec2 a_TexturePosition;" + 
      "varying vec2 v_TexturePosition;" + 
      "void main() {" + 
      " gl_Position = a_Position * u_Matrix;" + 
      " v_TexturePosition = a_TexturePosition;" + 
      "}" 
     ); 
    int fragment_shader = PageRenderer.loadShader(
      GLES20.GL_FRAGMENT_SHADER, 
      "precision mediump float;" + 
      "varying vec2 v_TexturePosition;" + 
      "uniform sampler2D u_Texture;" + 
      "void main() {" + 
      " gl_FragColor = texture2D(u_Texture, v_TexturePosition);" + 
      "}" 
     ); 

스케일링 및하지만 번역 이유를 알아낼 수 없습니다 예상대로 회전 작업은하지 않습니다. 최근까지 OpenGL을 사용하지 않았습니다.

translateM 왼쪽에서 텍스트를 '회전'시키지 않을 것으로 예상 했었습니다.

+0

이 같이 무슨 뜻입니까? 너는 무엇을 기대 했는가? 또한 쉐이더를 보여줄 수 있습니까? – Tim

+0

@ 확실한 것. 세부 사항이 부족해서 죄송합니다. 나는 셰이더 코드와 이미지를'translateM'없이 보이는 방식으로 추가했다. 나는'translateM'이 이미지를 왼쪽으로 옮길 것을 기대하고있었습니다. – MeanEYE

+0

아, 죄송합니다. 셰이더 코드를 다시 보았으니 문제가 발견되었습니다. :) 감사. – MeanEYE

답변

11

gl_Position을 계산할 때 변수의 순서가 중요합니다! 세계 행렬이 먼저 간 다음 정점 좌표가옵니다. 질문을 할 때 나는 이것을 알고 있었지만 쉐이더 코드는 Android OpenGL 튜토리얼에서 가져온 것이므로주의를 기울이지 않았다. 도자기를 만나십시오. 자습서가 올바르지 않습니다!

올바른 쉐이더 코드 :

int vertex_shader = PageRenderer.loadShader(
      GLES20.GL_VERTEX_SHADER, 
      "uniform mat4 u_Matrix;" + 
      "attribute vec4 a_Position;" + 
      "attribute vec2 a_TexturePosition;" + 
      "varying vec2 v_TexturePosition;" + 
      "void main() {" + 
      " gl_Position = u_Matrix * a_Position;" + 
      " v_TexturePosition = a_TexturePosition;" + 
      "}" 
     ); 
    int fragment_shader = PageRenderer.loadShader(
      GLES20.GL_FRAGMENT_SHADER, 
      "precision mediump float;" + 
      "varying vec2 v_TexturePosition;" + 
      "uniform sampler2D u_Texture;" + 
      "void main() {" + 
      " gl_FragColor = texture2D(u_Texture, v_TexturePosition);" + 
      "}" 
     ); 
+0

가장 끔찍한 것은 간단한 모양을 그릴 때이 버그가 보이지 않으며 복잡한 모양을 그릴 때 재앙이된다는 것입니다. MeanEYE에 감사드립니다 !!! –

+0

나는 똑같은 문제를 겪고 있지만 솔루션은 오직 나를 위해 셰이더를 충돌시킵니다. 나는 gl_position = a_Position * u_Matrix'를 할 때만 렌더링 할 수 있습니다. 나는 뷰와 프로젝션 (u_Matrix를 계산하기 위해)의 곱셈 순서를 변경하는 것을 시도해 보았다. 어떤 아이디어? V와 M을 바꿀 때 즉시 작업 했습니까? 아니면 먼저 다른 작업을해야합니까? – Navigateur

+0

내가 올바르게 기억하면 바로 작동합니다. 아마도 쉐이더에 뭔가 다른 문제가있을 수 있습니다. OpenGL에 대한 나의 경험은 정말로 제한되어 있습니다. 나는 새 질문을 게시하는 것이 좋습니다. – MeanEYE