2012-04-26 4 views
0

Спасибо за ваши ответы. Ниже приведена версия java/windows без текстуры, чтобы сэкономить все, что связано с различными проблемами, связанными с Android. Я пересмотрел Move(), как было предложено, и спрайт все еще неустойчив. Похоже, что он шевелятся шелковым глазом, ведь он всего лишь 1 квад - не очень сложный.Android OpenGL Simple Sprite Flicker Issue

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 выборки, что могло бы помочь, но возможно по-прежнему иногда мерцает, если в графическом процессоре имеется некоторая ошибка округления.

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