在opengl es android中的随机位置绘制多个立方体
Posted
技术标签:
【中文标题】在opengl es android中的随机位置绘制多个立方体【英文标题】:Drawing multiple cubes at random positions in opengl es android 【发布时间】:2012-03-26 20:21:05 【问题描述】:使用 OpenGL ES 我正在渲染一个简单的立方体类,将它绘制在屏幕的中心。但是,我希望能够在屏幕上随机位置绘制多个这样的立方体,但不知道如何。这是我的自定义表面视图,它将多维数据集呈现为私有类。我没有包括我的主要 ActivityManager,因为它不是问题。
public class TouchSurfaceView extends GLSurfaceView
private final float TRACKBALL_SCALE_FACTOR=52.0f;
private final float TOUCH_SCALE_FACTOR=100.0f/320;
private MyGLRenderer mRenderer;
private float mPreviousX;
private float mPreviousY;
public TouchSurfaceView(Context context)
super(context);
// TODO Auto-generated constructor stub
mRenderer=new MyGLRenderer();
setRenderer(mRenderer);
setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
private class MyGLRenderer implements GLSurfaceView.Renderer
private MyGLCube mCube;
public float mAngleX;
public float mAngleY;
public MyGLRenderer()
mCube=new MyGLCube();
@Override
public void onDrawFrame(GL10 gl)
// TODO Auto-generated method stub
gl.glDisable(GL10.GL_DITHER);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glClientActiveTexture(DRAWING_CACHE_QUALITY_HIGH);
// gl.glTranslatef(0, 0, -3.0f);
gl.glTranslatef(0, 0, -3.0f);
gl.glRotatef(mAngleX, 0, 1, 0);
gl.glRotatef(mAngleY, 1, 0, 0);
mCube.draw(gl);
@Override
public void onSurfaceChanged(GL10 gl, int width, int height)
// TODO Auto-generated method stub
gl.glViewport(0, 0, width, height);
float ratio=(float) width/height;
gl.glMatrixMode(GL10.GL_PROJECTION);
gl.glLoadIdentity();
gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config)
// TODO Auto-generated method stub
gl.glDisable(GL10.GL_DITHER);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
gl.glClearColor(0.5f, 2, 0.63f, 0.2f);
这里是MYGLCube
,其中包含用于构造立方体的顶点、索引和其他内容
public class MyGLCube
private float vertices[]=
0.3f,0.3f,-0.3f, // topFront Right
0.3f,-0.3f,-0.3f, //BottomFront Right
-0.3f,-0.3f,-0.3f, //BottomFront Left
-0.3f,0.3f,-0.3f, //topFront Left
0.3f,0.3f,0.3f, // topBack Right
0.3f,-0.3f,0.3f, //BottomBack Right
-0.3f,-0.3f,0.3f, //BottomBack Left
-0.3f,0.3f,0.3f, //topBack Left
;
private float rgbaVals[]=
1,1,0,.5f, // topFront Right color
0.25f,0, 0.8f,1, //BottomFront Right color
0,1,1,1, //BottomFront Left color
0.35f,0.26f,1,0.5f, //topFront Left color
0.23f,0.62f,3,0.2f, // topBack Right color
0.3f,0.43f,1,0.2f, //BottomBack Right color
0.2f, 0.3f, 0.73f,0.6f, //BottomBack Left color
0.6f, 0.9f, 0.65f, 0.2f //topBack Left color
;
private short pIndex[]=
3,4,0, 0,4,1, 3,0,1,
3,7,4, 7,6,4, 7,3,6,
3,1,2, 1,6,2, 6,3,2,
1,4,5, 5,6,1, 6,5,4
;
private FloatBuffer vertBuff, cBuff;
private ShortBuffer pBuff;
public MyGLCube()
ByteBuffer bBuff=ByteBuffer.allocateDirect(vertices.length*4);
bBuff.order(ByteOrder.nativeOrder());
vertBuff=bBuff.asFloatBuffer();
vertBuff.put(vertices);
vertBuff.position(0);
ByteBuffer pbBuff=ByteBuffer.allocateDirect(pIndex.length*2);
pbBuff.order(ByteOrder.nativeOrder());
pBuff=pbBuff.asShortBuffer();
pBuff.put(pIndex);
pBuff.position(0);
ByteBuffer colorBuff=ByteBuffer.allocateDirect(rgbaVals.length*4);
colorBuff.order(ByteOrder.nativeOrder());
cBuff=colorBuff.asFloatBuffer();
cBuff.put(rgbaVals);
cBuff.position(0);
public void draw(GL10 gl)
gl.glFrontFace(GL10.GL_CW);
gl.glEnable(GL10.GL_CULL_FACE);
gl.glEnable(GL10.GL_SMOOTH);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glCullFace(GL10.GL_BACK);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertBuff);
gl.glColorPointer(4, GL10.GL_FLOAT, 0, cBuff);
gl.glDrawElements(GL10.GL_TRIANGLES, pIndex.length, GL10.GL_UNSIGNED_SHORT, pBuff);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_CULL_FACE);
【问题讨论】:
【参考方案1】:翻译、旋转后必须使用glPushMatrix和glPopMatrix返回上一位置...
@Override
public void onDrawFrame(GL10 gl)
// TODO Auto-generated method stub
gl.glDisable(GL10.GL_DITHER);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
gl.glMatrixMode(GL10.GL_MODELVIEW);
gl.glLoadIdentity();
gl.glClientActiveTexture(DRAWING_CACHE_QUALITY_HIGH);
//Draw cube 1
gl.glPushMatrix();
gl.glTranslatef(-0.5f, 0, -3.0f);
gl.glRotatef(mAngleX, 0, 1, 0);
gl.glRotatef(mAngleY, 1, 0, 0);
mCube.draw(gl);
gl.glPopMatrix();
//Draw cube 2
gl.glPushMatrix();
gl.glTranslatef(0, 0, -3.0f);
gl.glRotatef(mAngleX, 0, 1, 0);
gl.glRotatef(mAngleY, 1, 0, 0);
mCube.draw(gl);
gl.glPopMatrix();
//Draw cube 3
gl.glPushMatrix();
gl.glTranslatef(0.5f, 0, -3.0f);
gl.glRotatef(mAngleX, 0, 1, 0);
gl.glRotatef(mAngleY, 1, 0, 0);
mCube.draw(gl);
gl.glPopMatrix();
【讨论】:
我什么也没画。在最后一次绘制立方体后,我不得不删除 gl.PopMatrix() 。它应该在不移除的情况下工作吗? @Mitulátbáti ,gl.PopMatrix() 调用的数量应该与 glPushMatrix() 相同,搜索代码中的某个地方是否有一个没有正确 popmatrix 的 pushmatrix 生成 1000 个立方体就可以了。但是有了这 3 个,当有 3-3 个 pop/pushmatrix 时它仍然不起作用。我不明白为什么...还是谢谢。【参考方案2】:实际绘制立方体的代码是以下三行:
gl.glTranslatef(0, 0, -3.0f);
gl.glRotatef(mAngleX, 0, 1, 0);
gl.glRotatef(mAngleY, 1, 0, 0);
mCube.draw(gl);
它移动坐标系,然后旋转它,然后绘制立方体。你想做的是将它移动到其他地方并在那里绘制立方体。像这样:
gl.glTranslatef(1.0, 0, 0f);
mCube.draw(gl);
【讨论】:
谢谢。把它移到别的地方?怎么样?让我们简单地说。如何在我的代码中与当前位置不同的位置绘制第二个立方体? 那行不通。它要么没有绘制,要么将立方体移动到屏幕外的某个地方。此外,它仍然完全没有解决问题的主要问题。我希望能够从同一个类中绘制多个这样的立方体。职位可能是第二个关注点。 它可能将立方体移出屏幕。我不知道您是如何设置投影的。你需要做的是学习OpenGL。这是一个很好的资源:@987654321@ OpenGL 是一个极低级别的 API。如果您正在寻找更高级别的东西,请查看 Unity。以上是关于在opengl es android中的随机位置绘制多个立方体的主要内容,如果未能解决你的问题,请参考以下文章
Framebuffer FBO渲染到纹理很慢,在Android上使用OpenGL ES 2.0,为啥?
Android应用开发 OpenGL ES -- 透视投影 和 正交投影
使用 OpenGL ES 1.0 在 Android 上进行离屏渲染的选项?