在 android 中使用 opengl 在 glsurfaceview 中显示 3D 模型的问题
Posted
技术标签:
【中文标题】在 android 中使用 opengl 在 glsurfaceview 中显示 3D 模型的问题【英文标题】:Problems showing a 3D model inside a glsurfaceview with opengl in android 【发布时间】:2014-10-14 22:50:32 【问题描述】:我正在尝试在 glsurfaceview 中绘制一个简单的立方体,但我没有得到清晰的表示。我只想画一个简单的立方体。
我自己的渲染器
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import android.opengl.GLSurfaceView.Renderer;
import android.opengl.GLU;
public class MyRenderer implements Renderer
Cube cube = new Cube();
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig arg1)
//set background color
gl.glClearColor(0.0f, 0.0f, 0.0f, 1f);
gl.glShadeModel(GL10.GL_SMOOTH);
// Buffer depth
gl.glClearDepthf(1.0f);
gl.glEnable(GL10.GL_DEPTH_TEST);
gl.glDepthFunc(GL10.GL_LEQUAL);
gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);
@Override
public void onDrawFrame(GL10 gl)
// Clean the screen and the buffer depth
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// replace actual matrix with the identity matrix
gl.glLoadIdentity();
// Move object 8 units in Z axis
gl.glTranslatef(0, 0, -8);
// Draw the cube
cube.draw(gl);
@Override
public void onSurfaceChanged(GL10 gl, int width, int height)
gl.glViewport(0, 0, width, height);
// Select proyection matrix
gl.glMatrixMode(GL10.GL_PROJECTION);
// Reset proyection matrix
gl.glLoadIdentity();
// Calculates the proportion of the window
GLU.gluPerspective(gl, 45.0f, (float) width / (float) height, 0.1f,100.0f);
// Model matrix view
gl.glMatrixMode(GL10.GL_MODELVIEW);
// Reset model3d matrix
gl.glLoadIdentity();
我自己的 3D 模型
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import javax.microedition.khronos.opengles.GL10;
public class Cube
private float vertices[] = //(x,y,z)
1.000000f, -1.000000f, -1.000000f,
1.000000f, -1.000000f, 1.000000f,
-1.000000f, -1.000000f, 1.000000f,
-1.000000f, -1.000000f, -1.000000f,
1.000000f, 1.000000f, -0.999999f,
0.999999f, 1.000000f, 1.000001f,
-1.000000f, 1.000000f, 1.000000f,
-1.000000f, 1.000000f, -1.000000f
;
private short caras[] = //
2, 3, 4,
8, 7, 6,
1, 5, 6,
2, 6, 7,
7, 8, 4,
1, 4, 8,
1, 2, 4,
5, 8, 6,
2, 1, 6,
3, 2, 7,
3, 7, 4,
5, 1, 8
;
private float colors[] =
1f, 0f, 0f, 1f
;
private FloatBuffer vertexBuffer;
private FloatBuffer colorBuffer;
private ShortBuffer indexBuffer;
public Cube()
ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length * 4);
vbb.order(ByteOrder.nativeOrder());
vertexBuffer = vbb.asFloatBuffer();
vertexBuffer.put(vertices);
vertexBuffer.position(0);
ByteBuffer ibb = ByteBuffer.allocateDirect(caras.length * 2);
ibb.order(ByteOrder.nativeOrder());
indexBuffer = ibb.asShortBuffer();
indexBuffer.put(caras);
indexBuffer.position(0);
ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length * 4);
cbb.order(ByteOrder.nativeOrder());
colorBuffer = cbb.asFloatBuffer();
colorBuffer.put(colors);
colorBuffer.position(0);
public void draw(GL10 gl)
gl.glFrontFace(GL10.GL_CCW);
gl.glEnable(GL10.GL_CULL_FACE);
gl.glCullFace(GL10.GL_BACK);
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
gl.glEnableClientState(GL10.GL_COLOR_ARRAY);
gl.glColorPointer(4, GL10.GL_FLOAT, 0, colorBuffer);
gl.glDrawElements(GL10.GL_TRIANGLES, caras.length, GL10.GL_UNSIGNED_SHORT, indexBuffer);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
gl.glDisable(GL10.GL_CULL_FACE);
gl.glDisableClientState(GL10.GL_COLOR_ARRAY);
实际结果的外图:http://i60.tinypic.com/v3zuvr.png
【问题讨论】:
【参考方案1】:两个问题:
OpenGL 索引基于 0,而此代码使用基于 1 的索引。 颜色数组需要包含每个顶点的颜色。由于有 8 个顶点,因此需要 8 种颜色,即 8 * 4 = 32 个浮点数。【讨论】:
以上是关于在 android 中使用 opengl 在 glsurfaceview 中显示 3D 模型的问题的主要内容,如果未能解决你的问题,请参考以下文章
在 OpenCL 内核 (android) 中读取 GL_UNSIGNED_BYTE OpenGL texture2D
Android Opengl OES 纹理渲染到 GL_TEXTURE_2D
Android Opengl OES 纹理渲染到 GL_TEXTURE_2D