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):
Đây là kết quả mong đợi:
Đâ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.
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? –