我目前正在努力在java / android中纹理.obj。
我把这个立方体作为.obj。
v 0.0 0.0 1.0
v 0.0 1.0 0.0
v 0.0 1.0 1.0
v 1.0 0.0 0.0
v 1.0 0.0 1.0
v 1.0 1.0 0.0
v 1.0 1.0 1.0
vn 0.0 0.0 1.0
vn 0.0 0.0 -1.0
vn 0.0 1.0 0.0
vn 0.0 -1.0 0.0
vn 1.0 0.0 0.0
vn -1.0 0.0 0.0
vt 0.0 0.0
vt 1.0 0.0
vt 1.0 1.0
vt 0.0 1.0
f 1/1/2 7/3/2 5/2/2
f 1/1/2 3/4/2 7/3/2
f 1/1/6 4/3/6 3/4/6
f 1/1/6 2/2/6 4/3/6
f 3/1/3 8/3/3 7/4/3
f 3/1/3 4/2/3 8/3/3
f 5/2/5 7/3/5 8/4/5
f 5/2/5 8/4/5 6/1/5
f 1/1/4 5/2/4 6/3/4
f 1/1/4 6/3/4 2/4/4
f 2/1/1 6/2/1 8/3/1
f 2/1/1 8/3/1 4/4/1
这是.obj解析器
public class Model {
private FloatBuffer mNormalsBuffer;
private ShortBuffer mIndexBuffer;
private FloatBuffer mVertexBuffer;
private FloatBuffer mTextureBuffer;
private List<Float> fTextureList = new ArrayList<Float>();
private List<Float> fNormalsList = new ArrayList<Float>();
private List<Float3D> textureList = new ArrayList<Float3D>();
private List<Float3D> normalsList = new ArrayList<Float3D>();
private List<Float> vertexList = new ArrayList<Float>();
private List<Short> indResults = new ArrayList<Short>();
private int indiSize;
private ArrayList<GroupObject> groupObjects;
// Android Stuff!
private Context context;
private int modelID;
class Float3D {
float x, y, z;
public Float3D(float parseFloat, float parseFloat2, float parseFloat3) {
x = parseFloat;
y = parseFloat2;
z = parseFloat3;
}
public float getX() {
return x;
}
public float getY() {
return y;
}
public float getZ() {
return z;
}
}
class Short3D {
short x, y, z;
public Short3D(short parseFloat, short parseFloat2, short parseFloat3) {
x = parseFloat;
y = parseFloat2;
z = parseFloat3;
}
public short getX() {
return x;
}
public short getY() {
return y;
}
public short getZ() {
return z;
}
}
class GroupObject {
String objectName;
public void setObjectName(String string) {
this.objectName = string;
}
public String getObjectName() {
return objectName;
}
}
public Model(Context activity, int mid) {
this.groupObjects = new ArrayList<GroupObject>();
this.modelID = mid;
this.context = activity;
loadFile();
}
private int loadFile() {
try {
InputStream inputStream;
BufferedReader in = null;
inputStream = context.getResources().openRawResource(modelID);
in = new BufferedReader(new InputStreamReader(inputStream));
loadOBJ(in);
Log.d("LOADING FILE", "FILE LOADED SUCESSFULLY====================");
} catch (IOException e) {
e.printStackTrace();
}
return 1;
}
private void loadOBJ(BufferedReader in) throws IOException {
Log.d("LOADING FILE", "STARTING!====================");
GroupObject defaultObject = new GroupObject();
GroupObject currentObject = defaultObject;
this.groupObjects.add(defaultObject);
String Line = null; // Stores ever line we read!
String[] Blocks; // Stores string fragments after the split!!
String CommandBlock; // Stores Command Blocks such as: v, vt, vn, g,
// etc...
try {
while ((Line = in.readLine()) != null) {
Line = Line.trim();
Blocks = Line.split(" ");
CommandBlock = Blocks[0];
if (CommandBlock.equals("g")) {
if (Blocks[1] == "default")
currentObject = defaultObject;
else {
GroupObject groupObject = new GroupObject();
groupObject.setObjectName(Blocks[1]);
currentObject = groupObject;
groupObjects.add(groupObject);
}
}
if (CommandBlock.equals("v")) {
vertexList.add(Float.parseFloat(Blocks[1]));
vertexList.add(Float.parseFloat(Blocks[2]));
vertexList.add(Float.parseFloat(Blocks[3]));
}
if (CommandBlock.equals("vt")) {
textureList.add(new Float3D(Float.parseFloat(Blocks[1]), Float.parseFloat(Blocks[2]), 0.0f));
}
if (CommandBlock.equals("vn")) {
normalsList.add(new Float3D(Float.parseFloat(Blocks[1]), Float.parseFloat(Blocks[2]),
Float.parseFloat(Blocks[3])));
}
if (CommandBlock.equals("f")) {
if (Blocks.length == 4) {
// faces with just 3 vert per face
for (int i = 1; i < Blocks.length; i++) {
short m = 1;
String[] values = Blocks[i].split("/");
short vn = Short.parseShort(values[2]);
short vt = Short.parseShort(values[1]);
short temp = Short.parseShort(values[0]);
temp = (short) (temp - m);
fNormalsList.add(normalsList.get(vn - m).x);
fNormalsList.add(normalsList.get(vn - m).y);
fNormalsList.add(normalsList.get(vn - m).z);
fTextureList.add(textureList.get(vt - m).x);
fTextureList.add(textureList.get(vt - m).y);
indResults.add(temp);
indiSize++;
}
} else {
// faces with 4 vert per face
Short3D[] indexTemp = new Short3D[4];
for (int i = 1; i < Blocks.length; i++) {
short m = 1;
String[] values = Blocks[i].split("/");
short vn = Short.parseShort(values[2]);
short vt = Short.parseShort(values[1]);
short temp = Short.parseShort(values[0]);
temp = (short) (temp - m);
Short3D fTemp = new Short3D(temp, vt, vn);
indexTemp[i - 1] = fTemp;
}
Short3D[] newFaceIndex = convertQuads(indexTemp);
short m = 1;
for (int i = 0; i < newFaceIndex.length; i++) {
indResults.add(newFaceIndex[i].x);
fNormalsList.add(normalsList.get(newFaceIndex[i].z - m).x);
fNormalsList.add(normalsList.get(newFaceIndex[i].z - m).y);
fNormalsList.add(normalsList.get(newFaceIndex[i].z - m).z);
fTextureList.add(textureList.get(newFaceIndex[i].y - m).x);
fTextureList.add(textureList.get(newFaceIndex[i].y - m).y);
fTextureList.add(textureList.get(newFaceIndex[i].y - m).z);
indiSize++;
}
}
}
}
System.out.println("done loading");
float[] vertResults = new float[vertexList.size()];
for (int i = 0; i < vertexList.size(); i++) {
vertResults[i] = vertexList.get(i);
}
mVertexBuffer = RenderUtils.buildFloatBuffer(vertResults);
short[] indctemp = new short[indResults.size()];
for (int i = 0; i < indResults.size(); i++) {
indctemp[i] = indResults.get(i);
}
mIndexBuffer = RenderUtils.buildShortBuffer(indctemp);
float[] normTemp = new float[fNormalsList.size()];
for (int i = 0; i < fTextureList.size(); i++) {
normTemp[i] = fNormalsList.get(i);
}
mNormalsBuffer = RenderUtils.buildFloatBuffer(normTemp);
float[] texTemp = new float[fTextureList.size()];
for (int i = 0; i < fTextureList.size(); i++) {
texTemp[i] = fTextureList.get(i);
// System.out.println(texTemp[i]+",");
}
mTextureBuffer = RenderUtils.buildFloatBuffer(texTemp);
} catch (Exception e) {
System.out.println(e);
System.out.println(Line);
}
}
public int getIndSize() {
return this.indiSize;
}
public FloatBuffer getVertices() {
return mVertexBuffer;
}
public FloatBuffer getTexCoords() {
return mTextureBuffer;
}
public ShortBuffer getIndices() {
return mIndexBuffer;
}
public FloatBuffer getNormals() {
return mNormalsBuffer;
}
public Short3D[] convertQuads(Short3D[] vert) {
Short3D[] newVert = new Short3D[6];
newVert[0] = vert[0];
newVert[1] = vert[1];
newVert[2] = vert[2];
newVert[3] = vert[0];
newVert[4] = vert[2];
newVert[5] = vert[3];
return newVert;
}
}
这是3d对象的纹理加载和绘制方法:
public void loadGLTexture(GL10 gl, Context context, int texid) {
// loading texture
Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(),
texid);
// generate one texture pointer
gl.glGenTextures(1, textures, 0);
// ...and bind it to our array
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// create nearest filtered texture
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
// Use Android GLUtils to specify a two-dimensional texture image from our bitmap
GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);
// Clean up
bitmap.recycle();
}
public void draw(GL10 gl) {
gl.glBindTexture(GL10.GL_TEXTURE_2D, textures[0]);
// GLES10.glEnableClientState(GLES10.GL_COLOR_ARRAY);
gl.glEnableClientState(GLES10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GLES10.GL_NORMAL_ARRAY);
gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glVertexPointer(3, GLES10.GL_FLOAT, 0, mVertexBuffer);
gl.glNormalPointer(GLES10.GL_FLOAT, 0, mNormalBuffer);
gl.glDrawElements(GLES10.GL_TRIANGLES, model.getIndSize(), GLES10.GL_UNSIGNED_SHORT, mIndices);
gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mTextureBuffer);
// GLES10.glDisableClientState(GLES10.GL_COLOR_ARRAY);
gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
gl.glDisableClientState(GLES10.GL_VERTEX_ARRAY);
gl.glDisableClientState(GLES10.GL_NORMAL_ARRAY);
}
最后是渲染器的绘制方法:
public void draw(GL10 gl) {
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glEnable(GL10.GL_LIGHTING);
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadMatrixf(ARToolKit.getInstance().getProjectionMatrix(), 0);
gl.glEnable(GL10.GL_CULL_FACE);
//gl.glFrontFace(GL10.GL_CW);
gl.glMatrixMode(GL10.GL_MODELVIEW);
if (ARToolKit.getInstance().queryMarkerVisible(markerID)) {
gl.glLoadMatrixf(ARToolKit.getInstance().queryMarkerTransformation(markerID), 0);
gl.glPushMatrix();
gl.glRotatef(-90f, 0.0f, 1.0f, 0.0f);
gl.glRotatef(90f, 1.0f, 0.0f, 0.0f);
gl.glRotatef(-90f, 0.0f, 0.0f, 1.0f);
gl.glRotatef(angle, 0.0f, 0.0f, 1.0f);
gl.glScalef(40, 40, 40);
//gl.glTranslatef(0, 0, 20);
shoe.draw(gl);
//cube.draw(gl);
gl.glPopMatrix();
if (spinning) angle += 5.0f;
}
纹理以某种方式展示但是在整个立方体上是非常凌乱而且没有在每一面显示.....我错过了什么?纹理缓冲看起来对我来说是正确的。 提前感谢任何想法。 干杯