2012-04-26 3 views
0

답장을 보내 주셔서 감사합니다. 아래는 Java/Windows 버전으로 다양한 안드로이드 관련 이슈들을 할인 할 수 있습니다. 제안 된대로 Move()를 수정했고 스프라이트는 여전히 불안했습니다. 실크가 부드럽게 움직이는 것처럼 보일 것입니다. 매우 컴 퓨팅이 많이 필요한 것은 아닙니다.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

당신은 샘플링의 결과는 당신을위한 약간 다른 모습을주고, 각 프레임 다를 수 있습니다 임의의 서브 픽셀 위치에있다, 그렇지 않은 경우, 항상 픽셀 경계에 정렬하여 스프라이트를 그릴하는 것이 도움이 될 수있는 당신의 텍스처 (이것은 깜박임으로 해석 될 수 있음).

에만 정수 위치에서 스프라이트를 그릴 다음 뷰포트 너비와 높이 (즉, gluOrtho2D(0,width,0,height) 일치하고 gluOrtho를 사용하는 것이 가장 쉬운 방법입니다. 당신은 당신의 '-5 5'투영 행렬을 유지하려면 화면 픽셀과 정확하게 스프라이트 텍셀을 정렬하는 방법을 계산하려면 수학을 수행해야합니다. LINEAR 샘플링에서 NEAREST 샘플링으로 변경하는 것이 좋습니다.하지만 가능성이 있습니다. GPU에 반올림 오류가있는 경우 가끔씩 깜박임.

0

시도해 본 결과 (Viewpad 10s, VegaComb 3.2) 그러나 3 초마다 눈에 띄게 결함이 생깁니다. GC와는 전혀 관계가 없습니다. 모든 정적 물건을 onSurfaceCreated으로 옮겼습니다. 효과가 거의 없었습니다. 이 동작을 설명 할 수있는 코드는 없습니다.

GLES20TriangleRenderer (API-Demos)은 더 부드럽게 작동하지만 결함도 발생합니다. 이 예제는 상당히 많은 작업을 수행 할 수 있지만 프레임 시간 문제를 설명 할 수있는 것은 아직 없습니다. Kube 예 (회전하는 루비 큐브) 은 글리치가 아닌 인 것처럼 보입니다. 아마도 이것은 인식 문제 일 것입니다.

이 문제를 해결하기 위해 할 수있는 일은 없을 것이라고 생각합니다.

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; 
    } 
}