[英]Frames appearing out of order on GLSurfaceView
我正在使用OpenGL ES編寫一個Android應用,並且在Android Studio隨附的Nexus 5仿真器中遇到此問題。 我已將代碼簡化為這個小應用程序,該應用程序簡單地繪制了一個來回的框:
package net.jesbus.stuttertest;
import android.app.Activity;
import android.opengl.GLSurfaceView;
import android.os.Bundle;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
public class MainActivity extends Activity
{
@Override
protected void onCreate(Bundle savedInstanceState)
{
super.onCreate(savedInstanceState);
// Create GLSurfaceView
GLSurfaceView glsv = new GLSurfaceView(this);
glsv.setEGLConfigChooser(8, 8, 8, 8, 16, 0);
// Create GLSurfaceView.Renderer
glsv.setRenderer(new GLSurfaceView.Renderer()
{
float step = 0;
boolean direction = false;
ShortBuffer iBuff;
FloatBuffer vBuff;
@Override
public void onSurfaceCreated(GL10 gl, EGLConfig config)
{
// Generate vertices index buffer
short[] pIndex = {0, 1, 2, 3};
ByteBuffer pbBuff = ByteBuffer.allocateDirect(pIndex.length * 2);
pbBuff.order(ByteOrder.nativeOrder());
iBuff = pbBuff.asShortBuffer();
iBuff.put(pIndex);
iBuff.position(0);
// Generate vertices buffer
float[] vs = new float[]
{
-1, +1, 0,
+1, +1, 0,
-1, -1, 0,
+1, -1, 0,
};
ByteBuffer bBuff = ByteBuffer.allocateDirect(vs.length * 4);
bBuff.order(ByteOrder.nativeOrder());
vBuff = bBuff.asFloatBuffer();
vBuff.put(vs);
vBuff.position(0);
}
@Override
public void onDrawFrame(final GL10 gl)
{
// Animation calculation
step += direction ? 0.02f : -0.02f;
if (step > 1) direction = false;
else if (step < 0) direction = true;
// Set background color
gl.glClearColor(0.7f, 0.7f, 1, 1);
// Clear screen
gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
// Set matrix to correct location
gl.glLoadIdentity();
gl.glTranslatef(-1 + step * 2, 0, 0);
gl.glScalef(0.25f, 0.4f, 1);
// Draw box
gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
gl.glFrontFace(GL10.GL_CW);
gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vBuff);
gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, 4, GL10.GL_UNSIGNED_SHORT, iBuff);
gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
}
@Override
public void onSurfaceChanged(GL10 gl, int width, int height)
{
}
});
setContentView(glsv);
}
}
我逐幀看了看它,它似乎沒有顯示下一幀,而是顯示了前一幀,然后跳過了原本應該顯示的幀並繼續:
圓圈表示在onDrawFrame中生成的幀,箭頭表示時間流。
我不完全知道OpenGL如何使用線程,但是請嘗試以下操作:
// Animation calculation
synchronized (this) {
step += direction ? 0.02f : -0.02f;
if (step > 1) direction = false;
else if (step < 0) direction = true;
}
或者如果編譯器同意並且OpenGL沒有鎖定,則使整個onDrawFrame()
方法同步...
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.