如何解决Java Open GL ES 2.0应用程序未显示模型
我正在使用Open GL ES 2.0开发一个小型Android应用程序,该应用程序应从.obj文件中加载3D模型并在屏幕上绘制该模型。问题是该模型没有出现在屏幕上。下面是代码。
MainActivity类
package com.example.robotArmControl;
import android.app.Activity;
import android.content.Context;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
public class MainActivity extends Activity {
private GLSurfaceView glSurfaceViewArm;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
glSurfaceViewArm = new MyGLSurfaceView(this);
setContentView(glSurfaceViewArm);
}
}
class MyGLSurfaceView extends GLSurfaceView {
public MyGLSurfaceView(Context context){
super(context);
setEGLContextClientVersion ( 2 );
setRenderer(new OpenGLRenderer(context));
}
}
OpenGLRenderer类
package com.example.robotArmControl;
import android.content.Context;
import android.opengl.GLES20;
import android.opengl.GLSurfaceView;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class OpenGLRenderer implements GLSurfaceView.Renderer
{
private Model baseModel;
private Context context;
public OpenGLRenderer(Context activityContext) {
context = activityContext;
}
public void onSurfaceCreated(GL10 unused,EGLConfig config) {
GLES20.glClearColor(0.3f,0.1f,0.9f,1.0f);
baseModel = new Model(context,"Base.obj");
}
public void onDrawFrame(GL10 unused) {
GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT);
baseModel.DrawModel();
}
public void onSurfaceChanged(GL10 unused,int width,int height) {
GLES20.glViewport(0,width,height);
float ratio = (float) width / height;
}
}
模型类
package com.example.robotArmControl;
import android.content.Context;
import android.opengl.GLES20;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.ArrayList;
public class Model {
int numberOfVertices = 0;
int numberOfNormals = 0;
int numberOfTextures = 0;
int numberOfFaces = 0;
private FloatBuffer verticesBuffer;
private FloatBuffer normalsBuffer;
private FloatBuffer textureBuffer;
private final String vertexShaderStr =
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = vPosition;" +
"}";
private final String fragmentShaderStr =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
private int program;
private int vertexShader;
private int fragmentShader;
private int colorHandle;
private int positionHandle;
float color[] = { 0.9f,1.0f };
public Model(Context context,String file) {
try {
InputStream input = context.getAssets().open(file);
BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(input),65536);
String lineContent;
String[] lineContentParts;
ArrayList<Float> verticesList = new ArrayList<>();
ArrayList<Float> texturesList = new ArrayList<>();
ArrayList<Float> normalsList = new ArrayList<>();
ArrayList<Face> facesList = new ArrayList<>();
while ((lineContent = bufferedReader.readLine()) != null) {
lineContent = lineContent.replace(" "," ");
lineContentParts = lineContent.split(" ");
if (lineContentParts[0].equalsIgnoreCase("v")) {
for (int i = 1; i < 4; i++) {
verticesList.add(Float.parseFloat(lineContentParts[i]));
}
numberOfVertices++;
}
if (lineContentParts[0].equalsIgnoreCase("vn")) {
for (int i = 1; i < 4; i++) {
normalsList.add(Float.parseFloat(lineContentParts[i]));
}
numberOfNormals++;
}
if (lineContentParts[0].equalsIgnoreCase("vt")) {
for (int i = 1; i < 3; i++) {
texturesList.add(Float.parseFloat(lineContentParts[i]));
}
numberOfTextures++;
}
int faceV;
int faceT;
int faceN;
if (lineContentParts[0].equalsIgnoreCase("f")) {
for(int i = 1; i < 4; i++) {
String[] faceParts = lineContentParts[i].split("/");
faceV = Integer.parseInt(faceParts[0]) - 1;
faceT = Integer.parseInt(faceParts[1]) - 1;
faceN = Integer.parseInt(faceParts[2]) - 1;
facesList.add(new Face(faceV,faceT,faceN));
}
numberOfFaces++;
}
}
int facesListSize = facesList.size();
ByteBuffer vb = ByteBuffer.allocateDirect(facesListSize * 4 * 3);
vb.order(ByteOrder.nativeOrder());
verticesBuffer = vb.asFloatBuffer();
ByteBuffer nb = ByteBuffer.allocateDirect(facesListSize * 4 * 3);
nb.order(ByteOrder.nativeOrder());
normalsBuffer = nb.asFloatBuffer();
ByteBuffer tb = ByteBuffer.allocateDirect(facesListSize * 4 * 2);
tb.order(ByteOrder.nativeOrder());
textureBuffer = tb.asFloatBuffer();
Face face;
int verticesListSize = verticesList.size();
int texturesListSize = texturesList.size();
int normalsListSize = normalsList.size();
for(int i = 0; i < facesListSize; i++) {
face = facesList.get(i);
verticesBuffer.put(verticesList.get(fixedIndex(verticesListSize,(int) face.V * 3,numberOfVertices)));
verticesBuffer.put(verticesList.get(fixedIndex(verticesListSize,(int) face.V * 3 + 1,(int) face.V * 3 + 2,numberOfVertices)));
textureBuffer.put(texturesList.get(fixedIndex(texturesListSize,face.T * 2,numberOfTextures)));
textureBuffer.put(texturesList.get(fixedIndex(texturesListSize,face.T * 2 + 1,numberOfTextures)));
normalsBuffer.put(normalsList.get(fixedIndex(normalsListSize,face.N * 3,numberOfNormals)));
normalsBuffer.put(normalsList.get(fixedIndex(normalsListSize,face.N * 3 + 1,face.N * 3 + 2,numberOfNormals)));
}
verticesBuffer.rewind();
textureBuffer.rewind();
normalsBuffer.rewind();
program = GLES20.glCreateProgram();
vertexShader = LoadShader(GLES20.GL_VERTEX_SHADER,vertexShaderStr);
fragmentShader = LoadShader(GLES20.GL_FRAGMENT_SHADER,fragmentShaderStr);
GLES20.glAttachShader(program,vertexShader);
GLES20.glAttachShader(program,fragmentShader);
GLES20.glLinkProgram(program);
GLES20.glUseProgram( program);
} catch (IOException e) { e.printStackTrace(); }
}
public void DrawModel() {
GLES20.glUseProgram(program);
positionHandle = GLES20.glGetAttribLocation(program,"vPosition");
GLES20.glEnableVertexAttribArray(positionHandle);
GLES20.glVertexAttribPointer(positionHandle,3,GLES20.GL_FLOAT,false,3 * 4,verticesBuffer);
colorHandle = GLES20.glGetUniformLocation(program,"vColor");
GLES20.glUniform4fv(colorHandle,1,color,0);
GLES20.glDrawArrays(GLES20.GL_TRIANGLES,numberOfVertices);
GLES20.glDisableVertexAttribArray(positionHandle);
}
private static class Face {
public long V;
public int T;
public int N;
public Face(long vertex,int texture,int normal) {
this.V = vertex;
this.T = texture;
this.N = normal;
}
}
private static int fixedIndex(int listSize,int index,int total) {
if (index >= listSize || index < 0) {
return total -1;
} else {
return index;
}
}
private int LoadShader(int type,String shaderSrc)
{
int shader;
int[] compiled = new int[1];
shader = GLES20.glCreateShader(type);
if (shader == 0)
return 0;
GLES20.glShaderSource(shader,shaderSrc);
GLES20.glCompileShader(shader);
GLES20.glGetShaderiv(shader,GLES20.GL_COMPILE_STATUS,compiled,0);
if (compiled[0] == 0)
{
GLES20.glDeleteShader(shader);
return 0;
}
return shader;
}
}
我没有从编译器中收到任何错误,但是仍然没有任何内容显示在屏幕上,并且我只能看到背景色。我分析了一些Open GL ES 2.0教程,但仍然无法在代码中找到问题。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。