I want to create a simple animation that shows a butterfly / a bird that flies using OpenGL, but I do not know how to approach the problem.
It would be a good solution to create a texture with two images to represent the animation since the animation is a small one? And if so, how should i exchange the pictures between them?
First load texture image by calling glTexImage2D
the other time load images to texture which already exists, using glTexSubImage2D
, which is significantly faster than glTexImage2D
call, and is very suitable for this type of animation.
Information from specification:
void glTexSubImage2D(
GLenum target,
GLint level,
GLint xoffset,
GLint yoffset,
GLsizei width,
GLsizei height,
GLenum format,
GLenum type,
const GLvoid * data
);
glTexSubImage2D
redefines a contiguous subregion of an existing two-dimensional texture image. The texels referenced by data replace the portion of the existing texture array withx
indicesxoffset
andxoffset + width - 1
, inclusive, and y indicesyoffset
andyoffset + height - 1
, inclusive. This region may not include any texels outside the range of the texture array as it was originally specified.
In case to get full texture image exchange you simply specify xoffset
and yoffset
equal to zero.
You may specify the texture names array like
char* textureNames[10] = { "...", "...", ..., "..." };
Then for texture data
GLbyte* textureData[10]; // 10 texture instances
load texture data with LoadTGA
rutine with automatical memory allocation
for (int i = 0; i < 10; i++) {
textureData[i] = LoadTGA(
textureNames[i],
/*... TEXTURE PARAMS MUST BE THE SAME FOR ALL IMAGES */
);
}
Loading first image
glTexImage2D(
GL_TEXTURE_2D, GL_RGB, 0, width, height, 0,
format, GL_UNSIGNED_BYTE, textureData[0]
);
in some rendering function
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;
Consider you use small amount of frames (textures), I suggest you to add some delay to rendering as the pictures will be changing extremely fast.
Or as you want to achieve realtime rendering speed, you can use some sort of async timer to switch between texture indices.
Or as you just want to change between 2 separate textures, I have answer previously how randomly apply textures to the surfaces. So it can be simply done by creating 2 simple 2d textures.
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
must be GLuint
type array. Texture generation call will be like glGenTextures(2, g_pnTextures)
.
Then sequentially change its index. And bind them to some surface.
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();
As you can see this loadTGA function returns memory buffer instead of OpenGL texture identifier (which causes the problems with value conversion).
Notice: The last techinque can be applied to the small amount of textures. If you want to achieve movie effect visualization or GIF animation, the first technique is the best way.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With