我是OpenGL的新手,从dev.android.com的小教程开始。示例代码包括用于方形几何的Square
类。该对象将在onSurfaceCreated()
方法中创建,并使用onDrawFrame()
绘制每一帧。以下是Square
(构造函数和draw-method)的示例代码:
public Square() {
// initialize vertex byte buffer for shape coordinates
ByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(squareCoords);
vertexBuffer.position(0);
// initialize byte buffer for the draw list
ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * 2);
dlb.order(ByteOrder.nativeOrder());
drawListBuffer = dlb.asShortBuffer();
drawListBuffer.put(drawOrder);
drawListBuffer.position(0);
// prepare shaders and OpenGL program
int vertexShader = MyGLRenderer.loadShader(
GLES20.GL_VERTEX_SHADER,
vertexShaderCode);
int fragmentShader = MyGLRenderer.loadShader(
GLES20.GL_FRAGMENT_SHADER,
fragmentShaderCode);
mProgram = GLES20.glCreateProgram(); // create empty OpenGL Program
GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program
GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
GLES20.glLinkProgram(mProgram); // create OpenGL program executables
}
public void draw(float[] mvpMatrix) {
// Add program to OpenGL environment
GLES20.glUseProgram(mProgram);
// get handle to vertex shader's vPosition member
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
// Enable a handle to the triangle vertices
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(
mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
// get handle to fragment shader's vColor member
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
// Set color for drawing the triangle
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
// get handle to shape's transformation matrix
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
MyGLRenderer.checkGlError("glGetUniformLocation");
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
MyGLRenderer.checkGlError("glUniformMatrix4fv");
// Draw the square
GLES20.glDrawElements(
GLES20.GL_TRIANGLES, drawOrder.length,
GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
我现在的问题是:我怎样才能在onSurfaceCreated()
创建对象但是在触摸事件之后?
我试图定义一个Square
变量但不在onSurfaceCreated()
初始化它,然后在绘制之前检查对象是否为null。触摸后我打电话给:
mSquare = new Square();
我知道这不是实现这个的好方法,但我只想尝试它是否有效。我会创建一个可绘制元素列表并在onDrawFrame()
方法中运行它,从列表对象中调用每个draw()
。但由于这种方法导致程序崩溃,我不知道如何继续。
您只能在OpenGL上下文中调用OpenGL。
存在此上下文的方法有3种:
1)onSurfaceCreated
- 创建/重新创建上下文时 - 您应该在此处加载资源
2)onSurfaceChanged
- 创建后和表面调整大小 - 您应该在此处指定与大小相关的变量
3)onDrawFrame
- 这里执行渲染 - 在这里你应该执行所有绘图命令
如果您尝试在上下文之外执行OpenGL调用,则很可能代码将无法正确执行。
Android和GL上下文是不同的,它们以自己的方式在不同的(管理)线程上运行,所以如果你想在触摸上创建一个你要创建对象的方块,你必须在GLcontext中这样做
在render()/或draw()循环中
if (touch_class.isAddedBody){
mSquare.createBody();
touch_class.isAdded = false;
}