2012-04-26 110 views
0

感謝您的回覆。下面是一個沒有紋理的java/windows版本,只是爲了折扣任何與Android相關的各種問題。我按照建議修改了Move(),精靈仍然緊張不安。它看起來應該絲綢平滑,畢竟它只有1個四分之一 - 不是很計算密集型。Android OpenGL簡單雪碧閃爍問題

import java.awt.Frame; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.awt.event.MouseMotionListener; 
import java.awt.event.WindowAdapter; 
import java.awt.event.WindowEvent; 
import java.nio.ByteBuffer; 
import java.nio.ByteOrder; 
import java.nio.FloatBuffer; 

import javax.media.opengl.GL2; 
import javax.media.opengl.GLAutoDrawable; 
import javax.media.opengl.GLEventListener; 
import javax.media.opengl.awt.GLCanvas; 
import javax.media.opengl.fixedfunc.GLMatrixFunc; 
import javax.media.opengl.glu.GLU; 

import com.jogamp.opengl.util.Animator; 

public class Practice implements GLEventListener, MouseMotionListener { 

    static GLCanvas canvas = new GLCanvas(); 
    static Animator anim = new Animator(canvas); 
    static Frame frame = new Frame(); 
    private GLU glu; 
    private FloatBuffer vertBuff; 
    private ByteBuffer indBuff; 
    private static float[] color = new float[]{1,1,1,1}; 
    private static float xpos; 
    private static float vel = 100f; 
    private static long lastTime = -1; 

    @Override 
    public void display(GLAutoDrawable drawable) { 
     GL2 gl = drawable.getGL().getGL2(); 
     gl.glClear(GL2.GL_COLOR_BUFFER_BIT | GL2.GL_DEPTH_BUFFER_BIT); 

     gl.glEnableClientState(GL2.GL_VERTEX_ARRAY); 
     gl.glVertexPointer(3,GL2.GL_FLOAT,0,vertBuff); 

     gl.glMatrixMode(GLMatrixFunc.GL_MODELVIEW); 
     gl.glLoadIdentity(); 
     gl.glColor4fv(color,0); 
     Move(gl); 
     gl.glDrawElements(GL2.GL_TRIANGLES,6,GL2.GL_UNSIGNED_BYTE,indBuff); 

    } 

    private void Move(GL2 gl){ 

     long time = System.currentTimeMillis(); 
     long timeStep = 0; 
     if(lastTime != -1){ 
      timeStep = time - lastTime; 
     } 
     if(timeStep < 20){ 
      try {Thread.sleep(20-timeStep);} catch (InterruptedException e) {e.printStackTrace();} 
     } 
     lastTime = time; 

     xpos += vel * timeStep/1000f; 
     if(xpos>500){ 
      xpos = 500; 
      vel *= -1; 
     } 
     if(xpos<-500){ 
      xpos = -500; 
      vel *= -1; 
     } 
     gl.glTranslatef(xpos,0.0f,0.0f); 
     gl.glScalef(50.0f,50.0f,1.0f); 
    } 

    @Override 
    public void dispose(GLAutoDrawable arg0) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void init(GLAutoDrawable drawable) { 
     GL2 gl = drawable.getGL().getGL2(); 

     gl.glClearColor(0,0,0,1); 
     glu = new GLU(); 

     float[] verts =  { 
           -0.5f, -0.5f, -1.0f, 
           0.5f, -0.5f, -1.0f, 
           0.5f, 0.5f, -1.0f, 
           -0.5f, 0.5f, -1.0f 
          }; 
     byte[] inds =  { 
           0,1,3, 1,2,3 
          }; 

     ByteBuffer bb = ByteBuffer.allocateDirect(48); 
     bb.order(ByteOrder.nativeOrder()); 
     vertBuff = bb.asFloatBuffer(); 
     vertBuff.put(verts); 
     vertBuff.position(0); 

     indBuff = ByteBuffer.allocateDirect(6); 
     indBuff.order(ByteOrder.nativeOrder()); 
     indBuff.put(inds); 
     indBuff.position(0); 

    } 

    @Override 
    public void reshape(GLAutoDrawable drawable, int x, int y, int width, 
      int height) { 
     GL2 gl = drawable.getGL().getGL2(); 
     if(height <=0)height=1; 
     float aspect = (float)width/height; 
     gl.glMatrixMode(GLMatrixFunc.GL_PROJECTION); 
     gl.glLoadIdentity(); 
     float[] ortho = { 
          (float)1/width,0,0,0, 
          0,(float)1/width*aspect,0,0, 
          0,0,1,0, 
          0,0,0,1 
         }; 
     //gl.glLoadMatrixf(ortho,0); 
     glu.gluOrtho2D(-width,width,-height,height); 
    } 

    @Override 
    public void mouseDragged(MouseEvent e) { 
     // TODO Auto-generated method stub 

    } 

    @Override 
    public void mouseMoved(MouseEvent e) { 
     // TODO Auto-generated method stub 
     float R = (float)1/frame.getWidth()*e.getX(); 
     float B = (float)1/frame.getHeight()*e.getY(); 
     color = new float[]{R,.2f,B,1.0f}; 
    } 

    public static void close(){ 
     anim.stop(); 
     frame.dispose(); 
     System.exit(0); 
    } 

    public static void main(String[] args) { 
     canvas.addGLEventListener(new Practice()); 
     canvas.addMouseMotionListener(new Practice()); 

     frame.add(canvas); 
     frame.setSize(500,300); 

     frame.addWindowListener(new WindowAdapter() { 
      public void windowClosing(WindowEvent e){ 
       close(); 
      }; 
     }); 

     frame.setVisible(true); 
     anim.start(); 
     canvas.requestFocus(); 
    } 

} 

回答

0

您可能會發現它有助於繪製你的精靈總是對齊像素邊界,否則,如果它是隨機的子像素位置採樣的結果將是不同的每一幀,爲您提供略微不同的外觀您紋理(這可以被解釋爲閃爍)。

最簡單的方法是使用gluOrtho來匹配你的視口寬度和高度(例如gluOrtho2D(0,width,0,height),然後只在整數位置繪製小精靈,如果你想保留'-5到5'的投影矩陣,你必須做數學題,要弄清楚如何正確地與屏幕的像素排列你的精靈紋理元素了。

另一種選擇可能是嘗試從LINEAR採樣更改爲NEAREST採樣,可能會有所幫助,但可能可能如果GPU中存在舍入誤差,則偶爾會閃爍。

0

嘗試過(Viewpad 10s,VegaComb 3.2);它運行平穩時間,但每3秒鐘就會出現明顯的故障。與GC無任何關係。我將所有靜態內容移至onSurfaceCreated,幾乎沒有影響。代碼中沒有任何東西可以解釋這種行爲。

GLES20TriangleRenderer(API-Demos)運行更平穩,但也有小故障。請注意,這個例子做了很多工作,但仍然沒有任何東西可以解釋任何幀時間問題。 Kube示例(旋轉Rubics立方體)似乎沒有小故障,也許這是一個看法問題。

我不認爲有什麼可以解決這個問題。

0

在HTC Desire S上測試它。 工作正常,除了偶爾出現故障。

仍限制幀率可以使其更好。 你可以改變你的「移動」方法,如:

long lastTime = -1; 
private void Move(GL10 gl) { 
    gl.glTranslatef(xpos,0.0f,0.0f); 

    long time = System.currentTimeMillis(); 
    long timeStep = 0; 
    if(lastTime != -1){ 
     timeStep = time - lastTime; 
    } 
    if(timeStep < 20){ 
     try {Thread.sleep(20-timeStep);} catch (InterruptedException e) {e.printStackTrace();} 
    } 
    lastTime = time; 

    xpos += vel * timeStep/1000.0f; 
    if(xpos>5*aspect){ 
     xpos = 5*aspect; 
     vel *= -1; 
    } 
    if(xpos<-5*aspect){ 
     xpos = -5*aspect; 
     vel *= -1; 
    } 
}