2013-03-27 21 views
5

Tôi gặp phải một số vấn đề. các bạn thử nó đi.Android OpenGL ES 2.0: Mô hình khối lập phương không chỉ bị bóp méo (quan điểm sai?), Mà còn các khuôn mặt được nạp sai (đỉnh không đúng?)

Tôi không thể lấy khối lập phương để tải chính xác. Tôi đã có thể làm cho nó xoay độc đáo trên tất cả các trục, mặc dù. (số nhiều "trục" là "trục"?)

Tôi chưa mạo hiểm với ánh sáng và kết cấu, vì vậy tôi xin lỗi nếu bạn dường như không thể tạo ra mô hình.

Đây là những gì nó trông giống như ngay bây giờ (ảnh chụp của một mô hình tự do-spinning):

Snapshot of the cube. No depth shown yet.

Đây là kết quả mong đợi:

Blender model. Expectations are too high, sir.

Đây là mã cho số GLSurfaceView.Renderer:

package dd.ww; 

import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.opengles.GL10; 
import android.content.Context; 
import android.opengl.GLES20; 
import android.opengl.GLSurfaceView.Renderer; 
import android.opengl.Matrix; 

public class Render implements Renderer { 

    private Context context; 
    private Cube cube; 

    private float[] modelViewProjectionMatrix = new float[16]; 
    private float[] projectionMatrix = new float[16]; 
    private float[] viewMatrix = new float[16]; 
    private float[] rotationMatrix = new float[16]; 
    private float angle = 0f; 

    public Render(Context context) { 
     this.context = context; 
    } 

    @Override 
    public void onSurfaceCreated(GL10 unused, EGLConfig config) { 
     GLES20.glClearColor(1f, 1f, 1f, 1f); 
     cube = new Cube(context); 
    } 

    @Override 
    public void onSurfaceChanged(GL10 unused, int width, int height) { 
     GLES20.glViewport(0, 0, width, height); 
     float ratio = (float) width/(float) height; 
     Matrix.frustumM(projectionMatrix, 0, -3f, 3f, -3f, 3f, 1f, 10f); 
    } 

    @Override 
    public void onDrawFrame(GL10 unused) { 
     GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); 
     //Camera position 
     Matrix.setLookAtM(viewMatrix, 0, 0f, 0f, -4f, 0f, 0f, 0f, 0f, 1f, 0f); 
     // projection x view = modelView 
     Matrix.multiplyMM(modelViewProjectionMatrix, 0, projectionMatrix, 0, viewMatrix, 0); 
     //Creating rotation matrix 
     Matrix.setRotateM(rotationMatrix, 0, angle, 0f, 0f, -1f); 
     //rotation x camera = modelView 
     Matrix.multiplyMM(modelViewProjectionMatrix, 0, rotationMatrix, 0, modelViewProjectionMatrix, 0); 
     Matrix.setRotateM(rotationMatrix, 0, angle, 0f, -1f, 0f); 
     Matrix.multiplyMM(modelViewProjectionMatrix, 0, rotationMatrix, 0, modelViewProjectionMatrix, 0); 
     Matrix.setRotateM(rotationMatrix, 0, angle, -1f, 0f, 0f); 
     Matrix.multiplyMM(modelViewProjectionMatrix, 0, rotationMatrix, 0, modelViewProjectionMatrix, 0); 

     cube.draw(modelViewProjectionMatrix); 

     angle += 0.7f; 
     if (angle > 360f) 
      angle = 0f; 
    } 

} 
của chúng tôi

Đây là mã cho lớp Cube, cùng với bộ nạp OBJ của nó. Các OBJ Loader được sử dụng để tải các mô hình OBJ đã được xuất khẩu từ Blender (đó là kết quả mong đợi của Cube, thể hiện trong Blender.):

package dd.ww; 

import java.io.BufferedReader; 
import java.io.InputStreamReader; 
import java.nio.ByteBuffer; 
import java.nio.ByteOrder; 
import java.nio.FloatBuffer; 
import java.nio.ShortBuffer; 
import java.util.ArrayList; 
import android.content.Context; 
import android.content.res.AssetManager; 
import android.opengl.GLES20; 
import android.util.Log; 

public class Cube { 
    private Context context; 
    private FloatBuffer vertexBuffer; 
    private ShortBuffer indexBuffer; 

    private int shaderProgram; 

    //TODO: Go to Google Code, find OpenGL ES 2.0 Programming Guide source code, Android, 
    //check in the ESShapes.java, and study the FloatBuffers... 

    public Cube(Context c) { 
     context = c; 
     loadCube("cube/cube.obj"); 
    } 

    private void loadCube(String filename) { 

     ArrayList<Float> tempVertices = new ArrayList<Float>(); 
     //ArrayList<Float> tempNormals = new ArrayList<Float>(); 
     ArrayList<Short> vertexIndices = new ArrayList<Short>(); 
     //ArrayList<Short> normalIndices = new ArrayList<Short>(); 

     try { 
      AssetManager manager = context.getAssets(); 
      BufferedReader reader = new BufferedReader(new InputStreamReader(manager.open(filename))); 
      String line; 
      while ((line = reader.readLine()) != null) { 
       if (line.startsWith("v")) { 
        tempVertices.add(Float.valueOf(line.split(" ")[1])); //vx 
        tempVertices.add(Float.valueOf(line.split(" ")[2])); //vy 
        tempVertices.add(Float.valueOf(line.split(" ")[3])); //vz 
       } 
       //    else if (line.startsWith("vn")) { 
       //     tempNormals.add(Float.valueOf(line.split(" ")[1])); //nx 
       //     tempNormals.add(Float.valueOf(line.split(" ")[2])); //ny 
       //     tempNormals.add(Float.valueOf(line.split(" ")[3])); //nz 
       //    } 
       else if (line.startsWith("f")) { 

        /* 
        vertexIndices.add(Short.valueOf(tokens[1].split("/")[0])); //first point of a face 
        vertexIndices.add(Short.valueOf(tokens[2].split("/")[0])); //second point 
        vertexIndices.add(Short.valueOf(tokens[3].split("/")[0])); //third point 
        normalIndices.add(Short.valueOf(tokens[1].split("/")[2])); //first normal 
        normalIndices.add(Short.valueOf(tokens[2].split("/")[2])); //second normal 
        normalIndices.add(Short.valueOf(tokens[3].split("/")[2])); //third 
        */ 
        //     for (int i = 1; i <= 3; i++) { 
        //      //String[] s = tokens[i].split("/"); 
        //      vertexIndices.add(Short.valueOf()); 
        //      //normalIndices.add(Short.valueOf(s[2])); 
        //     } 

        vertexIndices.add(Short.valueOf(line.split(" ")[1])); 
        vertexIndices.add(Short.valueOf(line.split(" ")[2])); 
        vertexIndices.add(Short.valueOf(line.split(" ")[3])); 
       } 
      } 

      float[] vertices = new float[tempVertices.size()]; 
      for (int i = 0; i < tempVertices.size(); i++) { 
       Float f = tempVertices.get(i); 
       vertices[i] = (f != null ? f : Float.NaN); 
      } 

      short[] indices = new short[vertexIndices.size()]; 
      for (int i = 0; i < vertexIndices.size(); i++) { 
       Short s = vertexIndices.get(i); 
       indices[i] = (s != null ? s : 1); 
      } 

      vertexBuffer = ByteBuffer.allocateDirect(vertices.length * 4).order(ByteOrder.nativeOrder()).asFloatBuffer(); 
      vertexBuffer.put(vertices).position(0); 

      indexBuffer = ByteBuffer.allocateDirect(indices.length * 2).order(ByteOrder.nativeOrder()).asShortBuffer(); 
      indexBuffer.put(indices).position(0); 


      int vertexShader = GLES20.glCreateShader(GLES20.GL_VERTEX_SHADER); 
      GLES20.glShaderSource(vertexShader, vertexCode); 
      GLES20.glCompileShader(vertexShader); 
      int fragmentShader = GLES20.glCreateShader(GLES20.GL_FRAGMENT_SHADER); 
      GLES20.glShaderSource(fragmentShader, fragmentCode); 
      GLES20.glCompileShader(fragmentShader); 

      shaderProgram = GLES20.glCreateProgram(); 
      GLES20.glAttachShader(shaderProgram, vertexShader); 
      GLES20.glAttachShader(shaderProgram, fragmentShader); 
      GLES20.glLinkProgram(shaderProgram); 

      int[] linked = new int[1]; 
      GLES20.glGetProgramiv(shaderProgram, GLES20.GL_LINK_STATUS, linked, 0); 
      if (linked[0] == 0){ 
       Log.d("DEBUG", "Shader code error."); 
       Log.d("DEBUG", GLES20.glGetProgramInfoLog(shaderProgram)); 
       GLES20.glDeleteProgram(shaderProgram); 
       return; 
      } 

      GLES20.glDeleteShader(vertexShader); 
      GLES20.glDeleteShader(fragmentShader); 




     } 
     catch (Exception e) { 
      Log.d("DEBUG", "Error.", e); 
     } 
    } 

    private String vertexCode = "" + 
      "attribute vec4 a_position; \n" + 
      "uniform mat4 mvpMatrix;  \n" + 
      "void main() {    \n" + 
      " gl_Position = a_position * mvpMatrix;\n" + 
      "}       \n"; 

    private String fragmentCode = "" + 
      "precision mediump float;     \n" + 
      "void main() {        \n" + 
      " gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0);\n" + 
      "}           \n"; 

    private int attribute_Position; 
    private int uniform_mvpMatrix; 

    public void draw(float[] mvpMatrix){ 
     GLES20.glUseProgram(shaderProgram); 
     attribute_Position = GLES20.glGetAttribLocation(shaderProgram, "a_position"); 
     GLES20.glVertexAttribPointer(attribute_Position, 3, GLES20.GL_FLOAT, false, 3 * 4, vertexBuffer); 
     GLES20.glEnableVertexAttribArray(attribute_Position); 
     uniform_mvpMatrix = GLES20.glGetUniformLocation(shaderProgram, "mvpMatrix"); 
     GLES20.glUniformMatrix4fv(uniform_mvpMatrix, 1, false, mvpMatrix, 0); 
     GLES20.glDrawElements(GLES20.GL_TRIANGLES, indexBuffer.capacity(), GLES20.GL_UNSIGNED_SHORT, indexBuffer); 
     GLES20.glDisableVertexAttribArray(attribute_Position); 
    } 
} 

Và cuối cùng, đây là tập tin đính kèm APK (Tải Lên đến Mediafire, không nên bị xóa. Đó là phần mềm miễn phí không được cấp phép). Tệp APK đính kèm được ký, xuất trực tiếp từ dự án của tôi và chỉ có thể chạy trên Gingerbread trở lên. (Đây là những gì OpenGL ES 2.0 là dành cho ...): Mediafire download link to the APK file.

Nếu bất kỳ ai sẵn sàng giúp tôi nhận ra những gì tôi đang làm sai, tôi sẽ vui mừng trong phần còn lại của cuộc đời tôi. This question here is the closest that I find when searching on SO that has a 40% chance my problem is related to. Thật không may, anh ta vẫn bị bóp méo mô hình của mình. Tất cả phần còn lại của câu hỏi tôi tìm thấy có vẻ là về kết cấu không hiển thị chính xác, dịch mô hình xung quanh, v.v ... Nhưng tôi sẽ cố gắng hết sức để tìm câu hỏi với các vấn đề tương tự như của tôi.

+0

Tôi đã nhận thấy rằng nhiều người hơn đang bỏ phiếu để đóng chương trình này. Tôi có thể hỏi tại sao, để trong tương lai tôi có thể tránh điều này và học hỏi từ những sai lầm ở đây? –

Trả lời

3

Holy Cow ...

Cuối cùng tôi đã làm việc đó.

Snapshot 1

Snapshot 2

vấn đề là làm thế nào OpenGL ES 2.0 ma trận làm việc.

Trích từ SO người dùng, Tim:

Tôi tin rằng nó phải được mvpMatrix * mRotationMatrix, nhưng bạn không được phép sử dụng ma trận tương tự như các đầu vào và đầu ra để chức năng đó, bạn cần phải sử dụng một ma trận tạm thời. Android.opengl.Matrix "Mảng nổi tương tự có thể được chuyển cho kết quả, lhs và/hoặc rh. Tuy nhiên, giá trị phần tử kết quả là không xác định nếu các phần tử kết quả trùng lặp với các phần tử lh hoặc rhs." Nếu điều đó không giúp bạn đăng toàn bộ mã.

Các văn bản in đậm có nghĩa là nếu bạn làm điều này:

//Creating rotation matrix 
Matrix.setRotateM(rotationMatrix, 0, angle, 0f, 0f, -1f); 

//rotation x camera = modelView  
Matrix.multiplyMM(modelViewProjectionMatrix, 0, modelViewProjectionMatrix, 0, rotationMatrix, 0); 

Matrix.setRotateM(rotationMatrix, 0, angle, 0f, -1f, 0f); 
Matrix.multiplyMM(modelViewProjectionMatrix, 0, modelViewProjectionMatrix, 0, rotationMatrix, 0); 

Matrix.setRotateM(rotationMatrix, 0, angle, -1f, 0f, 0f); 
Matrix.multiplyMM(modelViewProjectionMatrix, 0, modelViewProjectionMatrix, 0, rotationMatrix, 0); 

cube.draw(modelViewProjectionMatrix); 

Mà có vẻ như bình thường, khối lập phương sẽ xem xét sai lệch. Lý do là, lhs và rhs không nên giống như ma trận kết quả của bạn.

Nhưng, nếu bạn làm điều này:

//Creating rotation matrix 
Matrix.setRotateM(rotationMatrix, 0, angle, 0f, 0f, -1f); 

//rotation x camera = modelView 
float[] duplicateMatrix = Arrays.copyOf(modelViewProjectionMatrix, 16); 

Matrix.multiplyMM(modelViewProjectionMatrix, 0, duplicateMatrix, 0, rotationMatrix, 0); 

Matrix.setRotateM(rotationMatrix, 0, angle, 0f, -1f, 0f); 
duplicateMatrix = Arrays.copyOf(modelViewProjectionMatrix, 16); 
Matrix.multiplyMM(modelViewProjectionMatrix, 0, duplicateMatrix, 0, rotationMatrix, 0); 

Matrix.setRotateM(rotationMatrix, 0, angle, -1f, 0f, 0f); 
duplicateMatrix = Arrays.copyOf(modelViewProjectionMatrix, 16); 
Matrix.multiplyMM(modelViewProjectionMatrix, 0, duplicateMatrix, 0, rotationMatrix, 0); 

cube.draw(modelViewProjectionMatrix); 

Nó sẽ hiển thị một cách chính xác.

Where I found the helpful hint from.

Và đây là nơi mà tôi nhận ra lý do tại sao 3 người bình chọn để đóng câu hỏi này đi. Họ phải biết câu trả lời cho câu hỏi này ngay từ đầu, và muốn tôi tự mình tìm ra giải pháp. Hats off để họ ...

Tôi thề có Chúa, đây là một vấn đề khó khăn tôi cuối cùng đã chinh phục. Có 2 năm lãng phí cuộc sống xuống cống ...

+0

Điều này cuối cùng đã biến thành một ứng dụng Android? – Ogen

+0

@Clay Không may. Dự án này đã được hoãn lại vì tôi phải làm theo. –

+0

mã không hoạt động như mong đợi. vẫn bị xáo trộn. – andinrajesh