这是使用Visual Studio在Opengl 1中创建纹理动画的最佳方法

Which is the best way to create a Texture Animation in Opengl 1 using Visual Studio?

本文关键字:纹理 创建 动画 方法 最佳 Opengl Visual Studio      更新时间:2023-10-16

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

由于动画

很小,因此创建具有两个图像的纹理来表示动画是一个很好的解决方案吗? 如果是这样,我应该如何在它们之间交换图片?

首先通过调用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索引的现有纹理数组部分xoffsetxoffset + width - 1 、 包容性和 Y 指数 yoffsetyoffset + height - 1,包括。此区域可能不包括任何纹理数组最初范围之外的纹素指定。

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

您可以指定纹理名称数组,例如

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

然后对于纹理数据

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

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

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 个单独的纹理之间切换,我之前已经回答了如何将纹理随机应用于表面。因此,可以通过创建 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动画,第一种技术是最好的方法。