【转载】更新纹理及局部更新
版权声明:本文为CSDN博主「乌班图ysm」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/u012278016/article/details/105626570
更新纹理全部:
如果原来纹理ID对应的显存有数据,则删掉,并在显存中重新建立纹理。如果没有,直接建立纹理
void glTexImage2D (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const void *pixels);
更新纹理局部:
局部更新原来的纹理显存。
void glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
如下图把黑色区域中一部分更新成红色
代码如下:
建立更新
//顶点数据 struct Vertex { float x, y, z; float u, v; }; //纹理ID GLuint _texture; static FIBITMAP*readImage(const char* fileName) { //1 获取图片格式 FREE_IMAGE_FORMAT fifmt = FreeImage_GetFileType(fileName, 0); if(fifmt == FIF_UNKNOWN) { return 0; } //2 加载图片 FIBITMAP *dib = FreeImage_Load(fifmt, fileName, 0); FREE_IMAGE_COLOR_TYPE type = FreeImage_GetColorType(dib); //! 获取数据指针 FIBITMAP* temp = dib; dib = FreeImage_ConvertTo32Bits(dib); FreeImage_Unload(temp); BYTE* pixels = (BYTE*)FreeImage_GetBits(dib); int width = FreeImage_GetWidth(dib); int height = FreeImage_GetHeight(dib); for(int i = 0; i < width * height * 4; i+=4) { BYTE temp = pixels[i]; pixels[i] = pixels[i + 2]; pixels[i + 2] = temp; } return dib; } static void onInit() { FIBITMAP* arrayImage[2]; arrayImage[0] = readImage("../res/1.jpg"); arrayImage[1] = readImage("../res/2.png"); glGenTextures(1, &_texture); glBindTexture(GL_TEXTURE_2D, _texture); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); BYTE* pixels = (BYTE*)FreeImage_GetBits(arrayImage[0]); int width = FreeImage_GetWidth(arrayImage[0]); int height = FreeImage_GetHeight(arrayImage[0]); //该函数会把原来纹理对应的显存删掉,并在显存中重新建立纹理 glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, pixels); FreeImage_Unload(arrayImage[0]); { BYTE* pixels = (BYTE*)FreeImage_GetBits(arrayImage[1]); int width = FreeImage_GetWidth(arrayImage[1]); int height = FreeImage_GetHeight(arrayImage[1]); // glTexSubImage2D (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels); // target GL_TEXTURE_2D 2d纹理 // level 如果是mipmap的话 有很多等级,值更新哪一个等级纹理 // xoffset 更新的X位置 相对左下角0,0 点 // yoffset 更新的Y位置 相对左下角0,0 点 // width 更新的宽度 // height 更新的高度 // format 更新数据的颜色格式 // type 更新数据的颜色占用大小 // pixels 更新的颜色数据 // 该函数局部更新原来的纹理显存 glTexSubImage2D(GL_TEXTURE_2D, 0, 100, 100, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); } }
渲染
// 绘制 static void render(GLFWwindow * window) { glClearColor(0, 0, 0, 1); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); Vertex cubeVertices[] = { { -1.0f, -1.0f, 1.0f, 0, 0 }, { 1.0f, -1.0f, 1.0f, 1, 0 }, { 1.0f, 1.0f, 1.0f, 1, 1 }, { -1.0f, 1.0f, 1.0f, 0, 1 }, }; glMatrixMode(GL_MODELVIEW); glBindTexture(GL_TEXTURE_2D, _texture); glEnable(GL_DEPTH_TEST); glEnable(GL_TEXTURE_2D); glEnableClientState(GL_VERTEX_ARRAY); glEnableClientState(GL_TEXTURE_COORD_ARRAY); glVertexPointer(3, GL_FLOAT, sizeof(Vertex), &cubeVertices[0].x); glTexCoordPointer(2, GL_FLOAT, sizeof(Vertex), &cubeVertices[0].u); // 清成单位矩阵 glLoadIdentity(); // 产生一个矩阵 glTranslatef(0, 0, -4); glDrawArrays(GL_QUADS, 0, 4); glfwSwapBuffers(window); glfwPollEvents(); }