【问题标题】:Which is the best way to create a Texture Animation in Opengl 1 using Visual Studio?使用 Visual Studio 在 Opengl 1 中创建纹理动画的最佳方法是什么?
【发布时间】:2015-12-25 23:32:58
【问题描述】:

我想使用 OpenGL 创建一个显示蝴蝶/飞翔的鸟的简单动画,但我不知道如何解决这个问题。

既然动画很小,那么创建一个包含两个图像的纹理来表示动画会是一个很好的解决方案吗?如果是这样,我应该如何在他们之间交换图片?

【问题讨论】:

    标签: c++ opengl animation


    【解决方案1】:

    首先调用glTexImage2D加载纹理图片,另一次加载图片到已经存在的纹理,使用glTexSubImage2D,明显比glTexImage2D调用快,非常适合这种类型的动画。

    来自规范的信息:

    void glTexSubImage2D(
        GLenum target,  
        GLint level,  
        GLint xoffset,  
        GLint yoffset,  
        GLsizei width,  
        GLsizei height,  
        GLenum format,  
        GLenum type,  
        const GLvoid * data
    ); 
    

    glTexSubImage2D 重新定义现有的连续子区域 二维纹理图像。数据替换引用的纹素 现有纹理数组中带有x 索引xoffset 的部分 和 xoffset + width - 1 (含)和 y 索引 yoffsetyoffset + height - 1,包括在内。该区域可能不包括任何 纹理数组范围之外的纹素,因为它最初是 指定。

    如果要获得完整的纹理图像交换,您只需将xoffsetyoffset 指定为零。

    你可以像这样指定纹理名称数组

    char* textureNames[10] = { "...", "...", ..., "..." }; 
    

    然后是纹理数据

    GLbyte* textureData[10]; // 10 texture instances
    

    使用LoadTGA rutine 加载纹理数据并自动分配内存

    for (int i = 0; i < 10; i++) {
        textureData[i] = LoadTGA(
            textureNames[i],
            /*... TEXTURE PARAMS MUST BE THE SAME FOR ALL IMAGES */
        );
    }
    

    加载第一张图片

    glTexImage2D(
        GL_TEXTURE_2D, GL_RGB, 0, width, height, 0,
        format, GL_UNSIGNED_BYTE, textureData[0]
    );
    

    在某些渲染函数中

    static int imageIndex = 0;
    
    glTexSubImage2D(
        GL_TEXTURE_2D, 0, 0, 0, width, height,
        format, GL_UNSIGNED_BYTE, textureData[imageIndex]
    );
    
    imageIndex++;
    
    if (imageIndex == 10) // max index reached
        imageIndex = 0;
    

    考虑到您使用少量的帧(纹理),我建议您在渲染中添加一些延迟,因为图片的变化非常快。

    或者,如果您想实现实时渲染速度,您可以使用某种异步计时器在纹理索引之间切换。

    或者因为您只想在 2 个单独的纹理之间进行更改,我之前已经回答了 randomly apply textures to the surfaces。因此,只需创建 2 个简单的 2d 纹理即可完成。

    for (int i = 0; i < 2; i++) {
        g_pnTextures[i] = loadTGA(textureNames[i], g_pnTextures[i]);
    
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    
        glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
        glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
    }
    

    g_pnTextures 必须是 GLuint 类型的数组。纹理生成调用类似于glGenTextures(2, g_pnTextures)

    然后依次改变它的索引。并将它们绑定到某个表面。

    glBindTexture(GL_TEXTURE_2D, g_pnTextures[imageIndex++]);
    if (imageIndex == 10) // max index reached
        imageIndex = 0;
    
    glBegin(GL_QUADS);
    // specify texture coords
    glTexCoord2f(0.0f, 0.0f);
    glVertex2f(-1.0f, -1.0f);
    // specify texture coords
    glTexCoord2f(0.0f, 1.0f);
    glVertex2f(1.0f, -1.0f);
    // specify texture coords
    glTexCoord2f(1.0f, 1.0f);
    glVertex2f(1.0f, 1.0f);
    // specify texture coords
    glTexCoord2f(1.0f, 0.0f);
    glVertex2f(-1.0f, 1.0f);
    
    glEnd();
    

    正如你所见,这个 loadTGA 函数返回的是内存缓冲区而不是 OpenGL 纹理标识符(这会导致值转换出现问题)。

    注意:最后一个技术可以应用于少量纹理。如果要实现电影效果可视化或GIF动画,第一种技术是最好的方法。

    【讨论】:

    • 我无法在 textureData 中使用 loadTGA 加载纹理,因为它告诉我无法从 int 转换为 GLbyte*
    • @Maria:由于您创建了 2 个不同的纹理,因此可以应用更改纹理的其他策略。
    • 这是我的代码:code char* textureNames[2] = { "Textures\\bird1.tga", "Textures\\bird2.tga"};胶合鸟1纹理;胶水鸟2纹理; GLbyte* 纹理数据[2]; // 2 个纹理实例 glGenTextures(1, &bird1Texture); glGenTextures(1, &bird2Texture); //这里是错误 textureData[0] = loadTGA(textureNames[0], bird1Texture); textureData[0] = loadTGA(textureNames[1], bird2Texture); glTexImage2D(GL_TEXTURE_2D, GL_RGB, 0, 10, 10, 0, GL_RGB, GL_UNSIGNED_BYTE, textureData[0]);对不起,我不能缩进代码..
    • @Maria:这个问题是因为你的loadTGA函数像黑盒子一样。正如我从你的帖子中看到的,它加载 TGA 图像并调用 glBindTextureglTexImage 所以你实际上无法访问纹理数据缓冲区。
    • 非常感谢!我用了第二种方法,效果很好!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-08
    • 2011-01-13
    • 1970-01-01
    • 1970-01-01
    • 2022-08-23
    • 1970-01-01
    相关资源
    最近更新 更多