一种是直观的使用 glGetTexImage,然后获取数据到内存再贴上去,这种方法很慢。
另一种是使用 FBO,将纹理附加到 FBO,然后用 glCopyTexSubImage2D,不涉及跟内存交换数据,速度飞快。
方法一:获取纹理再拷贝
unsigned char * data = new unsigned char[normal_texture.width*normal_texture.height*4];
glBindTexture(GL_TEXTURE_2D, src_id); // 绑定 src_id
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); // 下载到 data
glBindTexture(GL_TEXTURE_2D, dest_id); // 绑定 dest_id
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data); // 上传
glBindTexture(GL_TEXTURE_2D, 0);
第二种方法:FBO 拷贝
GLuint fbo;
glGenFramebuffers(1, &fbo);
// bind the FBO
glBindFramebuffer(GL_READ_FRAMEBUFFER, fbo); // 绑定 FBO
// attach the source texture to the fbo
glFramebufferTexture2D(GL_READ_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, src_id, 0); // 绑定纹理到 FBO
// bind the destination texture
glBindTexture(GL_TEXTURE_2D, dest_id); // 绑定 dest_id
// copy from framebuffer (here, the FBO!) to the bound texture
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, width, height); // 从 FBO 直接拷贝到 dest_id
glBindTexture(GL_TEXTURE_2D, 0);
// unbind the FBO
glBindFramebuffer(GL_FRAMEBUFFER, 0);
Texture storage format Wallpaper engine uses a custom texture storage format converted by resourcecompiler.exe
Information | Size | Default value |
---|---|---|
File type indicator | 8 bytes | TEXV0005 |
Padding | 1 byte | Null terminator for string |
Extra file type indicator? | 8 bytes | TEXI0001 |
Padding | 1 byte | Null terminator for string |
Texture type | 1 byte | 4 => DXT5? 0 => JPEG? |
Unknown data | 15 bytes | To be reversed |
Width | 4 bytes | Image's width |
Height | 4 bytes | Image's height |
Unknown data | 5 bytes | To be reversed |
Container version | 8 bytes | TEXB0003 |
Padding | 1 byte | Null terminator for string |
Unknown data | 8 bytes | To be reversed |
Mip map levels | 4 bytes | The number of mipmaps stored for this texture |
Mipmap entry | x bytes | See Mipmap entries |
Information | Size | Default value |
---|---|---|
Width | 4 bytes | Mipmap's entry width |
Height | 4 bytes | Mipmap's entry height |
Compression flag | 4 bytes | Indicates if the content is compressed or not |
Next image size | 4 bytes | Image block size (uncompressed) |
Next image size | 4 bytes | Image block size (compressed) |
Mipmap pixels | x bytes | Actual bitmap data in the format specified |
GLuint GetDebugTextureId() {
static GLuint texture = 0;
if (texture != 0) {
return texture;
}
glGenTextures(1, &texture);
glBindTexture(GL_TEXTURE_2D, texture);
if (true) {
GLubyte data[] = {
255, 0, 0, 155,
0, 255, 0, 155,
0, 0, 255, 155,
255, 255, 255, 155 };
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
GLsizei width = 2;
GLsizei height = 2;
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
glGenerateMipmap(GL_TEXTURE_2D);
}
glBindTexture(GL_TEXTURE_2D, 0);
return texture;
}