2012-04-26 83 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; 
    } 
}