2012-10-03 28 views
6

Tôi đang cố gắng tạo một ứng dụng sẽ hiển thị văn bản bằng cách sử dụng OpenGL. Tôi nhận được hành vi bất ngờ khi tôi cố gắng sử dụng Matrix.translateM để di chuyển đối tượng được chỉ định đến một vị trí cụ thể. Tất cả các ma trận chuyển đổi khác hoạt động như tôi mong đợi.Android OpenGL ES 2.0: Không nhận được kết quả tôi muốn với Matrix.traslateM

Đây là những gì tôi nhận được khi tôi gọi Matrix.translateM(model_matrix, 0, -1.0f, 0, 0): result image

Đây là hình ảnh mà không cần dịch: enter image description here

Đây là mã renderer của tôi.

@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); 
} 

Và đây là mã số draw của tôi cho văn bản.

// 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); 

Shaders:

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);" + 
      "}" 
     ); 

Scaling và xoay công việc như mong đợi nhưng tôi không thể tìm ra lý do tại sao dịch thì không. Xin lưu ý rằng tôi đã không sử dụng OpenGL cho đến gần đây.

Tôi đã mong đợi translateM để di chuyển văn bản sang trái, chứ không phải 'xoay' văn ​​bản.

+0

là nó phải gì để trông như thế nào? Những gì bạn đã mong đợi? Ngoài ra, bạn có thể hiển thị trình đổ bóng của mình không. – Tim

+0

@Đảm bảo điều đó. Xin lỗi vì thiếu chi tiết. Tôi đã thêm mã shader và hình ảnh theo cách nó trông không có 'translateM'. Tôi đã mong đợi 'translateM' để di chuyển hình ảnh sang bên trái. – MeanEYE

+0

Ah, xin lỗi. Tìm thấy vấn đề bây giờ mà tôi đã có một cái nhìn thứ hai tại mã đổ bóng. :) Cảm ơn. – MeanEYE

Trả lời

11

Thứ tự các biến khi tính gl_Position là quan trọng! Ma trận thế giới đi đầu tiên và sau đó tọa độ đỉnh. Khi đặt câu hỏi tôi đã biết điều này, nhưng không chú ý vì mã đổ bóng được lấy từ hướng dẫn OpenGL của Android. Hãy là người làm đồ. Hướng dẫn không chính xác!

Đúng đang đổ bóng:

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

Điều khủng khiếp nhất là lỗi này là vô hình nếu bạn vẽ các hình dạng đơn giản và sẽ là thảm họa khi bạn vẽ các hình dạng phức tạp. Cảm ơn MeanEYE !!! –

+0

Tôi gặp vấn đề tương tự nhưng giải pháp của bạn chỉ làm đổ bóng cho tôi. Tôi chỉ có thể nhận được những thứ để render khi tôi làm 'gl_position = a_Position * u_Matrix'. Tôi thậm chí đã cố gắng thay đổi thứ tự nhân của xem và chiếu (để tính toán 'u_Matrix') vô ích. Ý tưởng nào? Máy của bạn có hoạt động ngay lập tức khi bạn đổi chỗ V và M hoặc bạn có phải làm điều gì khác trước không? – Navigateur

+0

Vâng, nó hoạt động ngay lập tức nếu tôi nhớ chính xác. Có lẽ có điều gì khác sai với trình đổ bóng của bạn nhưng chỉ trong trường hợp bạn làm đúng. Trải nghiệm của tôi với OpenGL thực sự rất hạn chế. Tôi khuyên bạn nên đăng câu hỏi mới về SO. – MeanEYE

Các vấn đề liên quan