【发布时间】:2014-04-10 19:27:14
【问题描述】:
这似乎是一个愚蠢的问题,但我觉得我需要问一下,这样我才能了解 openGl 缓冲区的工作原理。
我有两个缓冲区,顶点缓冲区和索引缓冲区。为了填充这些缓冲区,我正在解析一个 obj 文件。
解析数据后,我用我认为正确的数据和数据顺序填充缓冲区。
但是,当我调试代码时,我在缓冲区中看到了一些奇怪的东西。
首先是顶点缓冲区。我放入 Vbuffer 的前 3 个值是 0.99,-0.99,-0.7741 但是,当我通过逐步检查缓冲区时,这些值是 -92,112,125 这是因为这是一个 FloatBuffer 但作为一个字节缓冲区?
this.vertexBuffer = ByteBuffer.allocateDirect(VertexList.length * mBytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();
this.vertexBuffer.put(VertexList);
this.vertexBuffer.position(0);
我放入的索引缓冲区不同 4,1,2 当我检查它时,我似乎在每个值之间得到了一个额外的 0 4,0,1,0,2
this.IndexBuffer = ByteBuffer.allocateDirect(IndexList.length * 2).order(ByteOrder.nativeOrder()).asShortBuffer();
this.IndexBuffer.put(IndexList);
this.IndexBuffer.position(0);
在这个缓冲区中,我可以将数据作为 ShortBuffer 读取,即使它是一个字节缓冲区。 还有为什么其他值都是 0?
任何理解这一点的帮助将不胜感激。
更新!
这是我从 obj 文件中解析数据并填充缓冲区的完整代码。放入缓冲区的数据似乎是正确的。
public class RBLoadModelFromFile
{
/** How many bytes per float. */
private final int mBytesPerFloat = 4;
private Context context;
public FloatBuffer vertexBuffer;
public ShortBuffer IndexBuffer;
public float[] vertices;
public float[] normals;
public float[] uVs;
public short[] Ind;
private ArrayList<Short> indicies;
public int NumVertices;
public int NumIndicies;
public RBLoadModelFromFile(Context c)
{
context = c;
}
public void loadModel(String filename)
{
ArrayList<RBVector3> tempVertices = new ArrayList<RBVector3>();
ArrayList<RBVector3> tempNormals = new ArrayList<RBVector3>();
ArrayList<RBVector3> tempUVs = new ArrayList<RBVector3>();
ArrayList<Short> vertexIndices = new ArrayList<Short>();
ArrayList<Short> normalIndices = new ArrayList<Short>();
ArrayList<Short> textureIndices = new ArrayList<Short>();
indicies = 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 "))
{
RBVector3 tempVert = new RBVector3(0f,0f,0f);
tempVert.add(Float.valueOf(line.split(" ")[2]),Float.valueOf(line.split(" ")[3]),Float.valueOf(line.split(" ")[4]));
tempVertices.add(tempVert);
}
else if (line.startsWith("vn"))
{
RBVector3 tempNorm = new RBVector3(0f,0f,0f);
tempNorm.add(Float.valueOf(line.split(" ")[1]),Float.valueOf(line.split(" ")[2]),Float.valueOf(line.split(" ")[3]));
tempNormals.add(tempNorm);
}
else if (line.startsWith("vt"))
{
RBVector3 tempUV = new RBVector3(0f,0f,0f);
tempUV.add(Float.valueOf(line.split(" ")[1]),Float.valueOf(line.split(" ")[2]), 0f);
tempUVs.add(tempUV);
}
else if (line.startsWith("f"))
{
String tmp[] = line.split(" ");
vertexIndices.add(Short.valueOf(tmp[1].split("/")[0]));
textureIndices.add(Short.valueOf(tmp[1].split("/")[1]));
normalIndices.add(Short.valueOf(tmp[1].split("/")[2]));
vertexIndices.add(Short.valueOf(tmp[2].split("/")[0]));
textureIndices.add(Short.valueOf(tmp[2].split("/")[1]));
normalIndices.add(Short.valueOf(tmp[2].split("/")[2]));
vertexIndices.add(Short.valueOf(tmp[3].split("/")[0]));
textureIndices.add(Short.valueOf(tmp[3].split("/")[1]));
normalIndices.add(Short.valueOf(tmp[3].split("/")[2]));
}
}
Ind = new short[vertexIndices.size() + normalIndices.size() + textureIndices.size()];
vertices = new float[(vertexIndices.size() * 3) + (normalIndices.size() * 3) + (textureIndices.size() * 2)];
ArrayList<Float> vertInfo = new ArrayList<Float>();
for (int i = 0; i < vertexIndices.size(); i++)
{
Short v = vertexIndices.get(i);
vertInfo.add(tempVertices.get(v-1).x);
vertInfo.add(tempVertices.get(v-1).y);
vertInfo.add(tempVertices.get(v-1).z);
indicies.add((short) (v-1));
Short n = normalIndices.get(i);
vertInfo.add(tempNormals.get(n-1).x);
vertInfo.add(tempNormals.get(n-1).y);
vertInfo.add(tempNormals.get(n-1).z);
indicies.add((short) (n-1));
Short t = textureIndices.get(i);
vertInfo.add(tempUVs.get(t-1).x);
vertInfo.add(tempUVs.get(t-1).y);
indicies.add((short) (t-1));
}
for(int i = 0; i < indicies.size(); i++)
{
Ind[i] = indicies.get(i);
}
for (int i = 0; i < vertInfo.size(); i++)
{
vertices[i] = vertInfo.get(i);
}
createIndexBuffer(Ind);
createVertexBuffer(vertices);
NumIndicies = Ind.length;
NumVertices = vertices.length;
}
catch (Exception e)
{
Log.d("DEBUG", "Error.", e);
}
}
private void createVertexBuffer(float[] VertexList)
{
this.vertexBuffer = ByteBuffer.allocateDirect(VertexList.length * mBytesPerFloat).order(ByteOrder.nativeOrder()).asFloatBuffer();
this.vertexBuffer.put(VertexList);
this.vertexBuffer.position(0);
}
private void createIndexBuffer(short[] IndexList)
{
this.IndexBuffer = ByteBuffer.allocateDirect(IndexList.length * 2).order(ByteOrder.nativeOrder()).asShortBuffer();
this.IndexBuffer.put(IndexList);
this.IndexBuffer.position(0);
}
}
这是一个我正在尝试解析的简单立方体 obj 文件
v -0.500000 -0.500000 0.500000
v 0.500000 -0.500000 0.500000
v -0.500000 0.500000 0.500000
v 0.500000 0.500000 0.500000
v -0.500000 0.500000 -0.500000
v 0.500000 0.500000 -0.500000
v -0.500000 -0.500000 -0.500000
v 0.500000 -0.500000 -0.500000
vt 0.000000 0.000000
vt 1.000000 0.000000
vt 0.000000 1.000000
vt 1.000000 1.000000
vn 0.000000 0.000000 1.000000
vn 0.000000 1.000000 0.000000
vn 0.000000 0.000000 -1.000000
vn 0.000000 -1.000000 0.000000
vn 1.000000 0.000000 0.000000
vn -1.000000 0.000000 0.000000
f 1/1/1 2/2/1 3/3/1
f 3/3/1 2/2/1 4/4/1
f 3/1/2 4/2/2 5/3/2
f 5/3/2 4/2/2 6/4/2
f 5/4/3 6/3/3 7/2/3
f 7/2/3 6/3/3 8/1/3
f 7/1/4 8/2/4 1/3/4
f 1/3/4 8/2/4 2/4/4
f 2/1/5 8/2/5 4/3/5
f 4/3/5 8/2/5 6/4/5
f 7/1/6 1/2/6 5/3/6
f 5/3/6 1/2/6 3/4/6
我现在正在绘制一些东西,但顶点似乎离我们很远。
这是我现在的绘图方法
public void DrawModel(float[] mProjectionMatrix, float[] mViewMatrix, float[] mMVPMatrix, int mProgramHandle, int mMVPMatrixHandle, int mMVMatrixHandle, int mLightPosHandle, float[] mLightPosInEyeSpace)
{
mPositionHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Position");
mNormalHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_Normal");
mTextureUniformHandle = GLES20.glGetUniformLocation(mProgramHandle, "u_Texture");
mTextureCoordinateHandle = GLES20.glGetAttribLocation(mProgramHandle, "a_TexCoordinate");
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
// Bind the texture to this unit.
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureDataHandle);
// Tell the texture uniform sampler to use this texture in the shader by binding to texture unit 0.
GLES20.glUniform1i(mTextureUniformHandle, 0);
// This multiplies the view matrix by the model matrix, and stores the result in the MVP matrix
// (which currently contains model * view).
Matrix.multiplyMM(mMVPMatrix, 0, mViewMatrix, 0, mModelMatrix, 0);
// Pass in the modelview matrix.
GLES20.glUniformMatrix4fv(mMVMatrixHandle, 1, false, mMVPMatrix, 0);
// This multiplies the modelview matrix by the projection matrix, and stores the result in the MVP matrix
// (which now contains model * view * projection).
Matrix.multiplyMM(mMVPMatrix, 0, mProjectionMatrix, 0, mMVPMatrix, 0);
// Pass in the combined matrix.
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mMVPMatrix, 0);
// Pass in the light position in eye space.
GLES20.glUniform3f(mLightPosHandle, mLightPosInEyeSpace[0], mLightPosInEyeSpace[1], mLightPosInEyeSpace[2]);
// the vertex coordinates
VertexBuffer.position(TRIANGLE_VERTICES_DATA_POS_OFFSET);
GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false,
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, VertexBuffer);
GLES20.glEnableVertexAttribArray(mPositionHandle);
// the normal info
VertexBuffer.position(TRIANGLE_VERTICES_DATA_NOR_OFFSET);
GLES20.glVertexAttribPointer(mNormalHandle, 3, GLES20.GL_FLOAT, false,
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, VertexBuffer);
GLES20.glEnableVertexAttribArray(mNormalHandle);
// texture coordinates
VertexBuffer.position(TRIANGLE_VERTICES_DATA_TEX_OFFSET);
GLES20.glVertexAttribPointer(mTextureCoordinateHandle, 2, GLES20.GL_FLOAT, false,
TRIANGLE_VERTICES_DATA_STRIDE_BYTES, VertexBuffer);
GLES20.glEnableVertexAttribArray(mTextureCoordinateHandle);//GLES20.glEnableVertexAttribArray(shader.maTextureHandle);
// Draw with indices
GLES20.glDrawElements(GLES20.GL_TRIANGLES, NumIndicies , GLES20.GL_UNSIGNED_SHORT, IndexBuffer);
//checkGlError("glDrawElements");
}
【问题讨论】:
标签: java android memory buffer opengl-es-2.0