当前位置: 首页 > 知识库问答 >
问题:

在使用OpenGLES 2.0的Android上使用Gaffer的固定时间戳结巴了一些时间

杨良平
2023-03-14

我的游戏循环有一些小口吃。我正确(我认为)实现了https://gafferongames.com/post/fix_your_timestep/中的固定时间戳技术

我认为当技术被正确地实施时,精灵的动作是完全流畅的。我的代码没有产生100%的平滑,但一点也不差。

public static final int FRAME_RATE = 30;
public static final double DELTA_TIME = 1/(double)FRAME_RATE;

private double lastTimeStamp;
private double accumulator;

// An entity position in the game
public float oldX, x;

@Override
public void onDrawFrame(GL10 unused) {
    double now = (System.nanoTime() - lastTimeStamp)/1000000 * 0.001;

    if (now > 0.25) {
        now = 0.25;
    }

    lastTimeStamp = System.nanoTime();
    accumulator += now;

    while (accumulator >= DELTA_TIME) {
        tick(DELTA_TIME);
        accumulator -= DELTA_TIME;
    }

    double alpha = accumulator/DELTA_TIME;

    render(alpha);
}

public void tick(double dt) {
    oldX = x;

    x++; // increment entity x position
}

public void render(double alpha) {
    float xx = (x - oldX) * (float)alpha + oldX; // interpolated x position

    ShaderBasic.render(fooTexture, xx, 0); // render class
}
public void render(Texture texture, float x, float y) {
    //RENDERING
    glUseProgram(glIdProgram);

    //VERTICES
    glEnableVertexAttribArray(glPosition);
    glVertexAttribPointer(glPosition, 2, GL_FLOAT, false, 0, texture.vertexBuffer);

    //UVS
    glEnableVertexAttribArray(glUv);
    glVertexAttribPointer(glUv, 2, GL_FLOAT, false, 0, texture.uvBuffer[0]);

    //MODEL
    glUniform2f(glTrans, x, y); 

    //RENDERING
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, texture.glIdTexture);
    glUniform1i(glTexture, 0);
    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, texture.indexBuffer);

    //DISABLE
    glDisableVertexAttribArray(glPosition);
    glDisableVertexAttribArray(glUv);
    glBindTexture(GL_TEXTURE_2D, 0);

顶点着色器部分:

void main() {                       
    mat4 model = mat4(1.0,        0.0,       0.0, 0.0,
                      0.0,        1.0,       0.0, 0.0,
                      0.0,        0.0,       1.0, 0.0,
                      v_trans.x,  v_trans.y, 0.0, 1.0);

    mat4 projection = mat4(0.0036764, 0.0,        0.0, 0.0,
                           0.0,       0.0041666,  0.0, 0.0,
                           0.0,       0.0,        1.0, 0.0,
                           0.0,       0.0,        1.0, 1.0);

    gl_Position = projection * model * vec4(v_position, 0.0, 1.0);
    v_texCoord  = v_uv;                                           

}

纹理加载器类:

    private void loadImage(String imgPath, int frames) throws IOException {
        int[] id = new int[1];
        glGenTextures(1, id, 0);

        Bitmap img = BitmapFactory.decodeStream(Utils.getAssets().open(imgPath));
        glBindTexture(GL_TEXTURE_2D, id[0]);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // question
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); // question
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        GLUtils.texImage2D(GL_TEXTURE_2D, 0, img, 0);
        glBindTexture(GL_TEXTURE_2D, 0);

        glIdTexture = id[0];
        width = img.getWidth();
        height = img.getHeight();

        this.frameWidth = width/frames;
        this.frameHeight = height;

        img.recycle();
}

共有1个答案

云建木
2023-03-14

我的代码没有产生100%的平滑,但一点也不差。

你是不是一直打到60帧?如果你不是,那么你会得到一些微口吃,因为Android OpenGL ES使用三重缓冲和vsync,所以显示交换永远不会完全匹配你的应用程序端帧定时。

另一个问题:当我们使用小数部分大于0的(x,y)坐标时,纹理过滤一定是gl_linear?我注意到当我使用GL_NEAREST时,屏幕上呈现的sprite在屏幕中的某些位置被切片。我认为GL_NEAREST没有过滤所有纹理像素当我们有十进制不精确...

以后每个帖子请只问一个问题。

 类似资料:
  • 问题内容: 我在跑步时遇到崩溃,它指向。控制台中的错误是: 无法将类型“ Swift.Optional”(0x1192bf4a8)的值强制转换为“ NSTimeZone”(0x1192c0270)。 价值就是 我试图从Firebase中提取一个保存为字符串的Unix时间戳。将其转换为日期,然后再次将其另存为字符串,以便将其张贴在单元格标签上。 我从StackOverflow获得了这段代码。我插入了

  • 我不太理解时间戳的用法, 例如 用户创建文章,他们可以选择,系统也会自动存储。 a.我是否应该使和具有时区并设置UTC的时间戳? b.用户post字符串,然后将其转换为utc时间戳,如下所示使用并存储,当某人选择这一行时,将其显示为用户客户端时间反向使用 c.我使用到,是不是意味着服务器时间?我做得对吗? 我的想法是,我总是在数据库中插入utc时区时间戳,无论用户/客户端读取的地方,都将数据转换为

  • 本文向大家介绍Android进阶之使用时间戳计算时间差,包括了Android进阶之使用时间戳计算时间差的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了Android使用时间戳计算时间差的具体代码,供大家参考,具体内容如下 因当前项目需要计算时间差,进行数据处理,所以在Csdn上找了一下,之后修修补补是可以用的,建议大家如果用到项目中的话,可能需要把老的时间戳或者时间format存储在

  • 我想用树莓派实时捕捉带有时间戳的视频帧。视频由USB摄像头使用python代码中的ffmpeg()函数制作。如何保存当前由USB摄像头在树莓派中制作的视频帧? 我尝试使用opencv的三个函数。cv2。VideoCapture可检测视频,保存帧。以下是代码,为简洁起见,未提及包含的库。 该代码保存了以前由网络摄像头制作的视频帧。它不保存当前由网络摄像头录制的视频帧。

  • 从MariaDB转移到postgres-10后,我得到下面的错误我使用Django-orm 函数日期格式(带时区的时间戳,未知)不存在第1行:选择(日期格式(在,'%h%p')创建)为“以小时为单位”,求和(。。。 提示:没有与给定名称和参数类型匹配的函数。您可能需要添加显式类型转换。 谁能解释一下哪里出了问题。非常感谢。

  • 问题内容: 这个问题已经在这里有了答案 : 我应该在MySQL中使用datetime或timestamp数据类型吗? (39个答案) 6年前关闭。 我已经搜索了此文件,但没有明确的答案(尤其是后者)。在什么情况下应该使用日期时间或时间戳记? 问题答案: 假设您使用的是MS SQL Server(不是,请参见 下面 的 更新 ): 一个表只能有一个时间戳列。每次插入或更新包含时间戳列的行时,都会更新