所以我有一个方法,从一个ByteBuffer创建一个IntBuffer:
public static IntBuffer directIntBuffer(int[]buffer){
ByteBuffer bb = ByteBuffer.allocateDirect(4*buffer.length);
bb.order(ByteOrder.nativeOrder());
IntBuffer ib = bb.asIntBuffer();
ib.put(buffer).flip();
return ib;
}
在另一个类的构造函数中,我初始化这些intbuffer之一,并填充它嵌套的for循环:
EDIT:所以这是我的完整构造函数。我填充FloatBuffer FBVertices与实际顶点坐标和IntBuffer IBVerticesIndex与索引。后来,我用GL11. gldrawelements (GL11)绘制了这些。GL_TRIANGLES IBVerticesIndex);
public sphereHelper(float fRadius, int iSlices, int iStacks)
{
FBVertices = GLDrawHelper.directFloatBuffer(new float[iSlices*iStacks*4*3]);
FBVertices.clear();
IBVerticesIndex = GLDrawHelper.directIntBuffer(new int[iSlices*iStacks*4]);
IBVerticesIndex.clear();
int index=0;
float verticalDegreePerStack= (float)Math.PI/iStacks; //1*Pi because we only want the height of the sphere once (from -PI/2 to PI/2)
float horizontalDegreePerSlice = 2.0f* (float)Math.PI/iSlices; //2*Pi because of unit circle/polar coordinates going once around the sphere
for (int k=0; k< iStacks; k++)
{
//overall vertical angle
float rho= (float)k*verticalDegreePerStack;
//sinus of that angle
float srho =(float) (Math.sin(rho));
float crho = (float) (Math.cos(rho));
//sinus and cosinus of vertical angle+ angle of 1 stack
float srhodrho= (float) (Math.sin(rho + verticalDegreePerStack));
float crhodrho = (float) (Math.cos(rho + verticalDegreePerStack));
for (int j=0; j<iSlices;j++)
{
//overall angle along the horizontal border (0 degree at full 2*PI circle)
float theta = (j==iSlices)? 0.0f : j*horizontalDegreePerSlice;
//sinus and cosinus
float stheta = (float)(-Math.sin(theta));
float ctheta = (float)(Math.cos(theta));
//coordinates of first vertex of current triangle
float x=stheta*srho;
float z=ctheta*srho;
float y=crho;
//put coordinates of first vertex into buffer
FBVertices.put(new float[]{x*fRadius,y*fRadius,z*fRadius});
//put index of first vertex of polygon in index array, increase index counter by one
if (IBVerticesIndex.position()<IBVerticesIndex.capacity())
{IBVerticesIndex.put(index);}
index++;
//second vertex
x = stheta*srhodrho;
z = ctheta*srhodrho;
y = crhodrho;
//put these coordinates into Buffer
FBVertices.put(new float[] {x*fRadius,y*fRadius,z*fRadius});
if (IBVerticesIndex.position()+2<IBVerticesIndex.capacity())
{
IBVerticesIndex.put(new int[] {index,index+1,index+2});}
index++;
System.out.println(IBVerticesIndex.position()+"/"+IBVerticesIndex.capacity());
}
IBVerticesIndex.flip();
FBVertices.flip();
}
}
我得到一个BufferOverflowException,在这个输出:
4/400 8/400 12/400 16/400 20/400 24/400 28/400 32/400 36/400 40/400
线程"main"出现异常java.nio.BufferOverflowException
所以它在缓冲区容量的十分之一溢出?我在一开始就清除了缓冲区,所以位置应该被重置。
感谢您的输入!
EDIT: +1对Arjan对原始问题的评论。我把Don的代码复制到我的机器上,它在Java 8上工作,也得到400/400作为输出。您是否在注释代码的其他地方设置了limit
?
你读过Buffer超类是如何工作的吗?具体地说,这个类有一个limit
属性,这个属性没有一个记录良好的初始值。写入超过limit
值会抛出一个BufferOverflowException
在我看来,你想使用这个IntBuffer
像一个原始数组,在这种情况下,在你的初始化例程中,你需要在调用flip()
后将limit
设置为capacity
,根据文档将limit
重置为mark
。