纹理在opengl中消失

textures vanishing in opengl

本文关键字:消失 opengl 纹理      更新时间:2023-10-16

我看到这个问题,在应用程序使用一两分钟后,纹理就会消失。为什么纹理会消失?3d立方体始终保持在屏幕上。纹理消失时,纹理所在的位置显示为白框。

我的DrawGLScene方法如下:

        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
            glLoadIdentity();   // Reset The Current Modelview Matrix
            glTranslatef(0.0f, 0.0f, -7.0f);    // Translate Into The Screen 7.0 Units
//rotquad is a value that is updated as the user interacts with the ui by +/-9 to rotate the cube
        glRotatef(rotquad, 0.0f, 1.0f, 0.0f);
        //cube code here
            RECT desktop;
            const HWND hDesktop = GetDesktopWindow();
            GetWindowRect(hDesktop, &desktop);
            long horizontal = desktop.right;
            long vertical = desktop.bottom;
            glMatrixMode(GL_PROJECTION);
            glPushMatrix();
            glLoadIdentity();
            glOrtho(-5.0, 3, 3, -5.0, -1.0, 10.0);
            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();
            glDisable(GL_CULL_FACE);
            glEnable(GL_TEXTURE_2D);
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glClear(GL_DEPTH_BUFFER_BIT);
            glColor4f(255.0f, 255.0f, 255.0f, 0.0f);
            if (hoverRight) {
                imageLoaderOut(outImage);
                imageLoaderIn(inImage);
                imageLoaderUp(upImage);
                imageLoaderLeft(leftHover);
                imageLoaderDown(upImage);
                imageLoaderRight(rightImage);
            }
    // code for hover left, up and down are the same as hover right code above 
        glDisable(GL_TEXTURE_2D);
        return TRUE;    // Keep Going
    }

该方法是imageLoad方法之一(其他被调用的方法几乎相同,除了位置。

        void imageLoaderOut(const char* value)
        {
            FIBITMAP* bitmap60 = FreeImage_Load(
                FreeImage_GetFileType(value, 0),
                value, PNG_DEFAULT);
            FIBITMAP *pImage60 = FreeImage_ConvertTo32Bits(bitmap60);
            int nWidth60 = FreeImage_GetWidth(pImage60);
            int nHeight60 = FreeImage_GetHeight(pImage60);
            glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, nWidth60, nHeight60, 0, GL_RGBA, GL_UNSIGNED_BYTE, (void*)FreeImage_GetBits(pImage60));
            FreeImage_Unload(pImage60);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glBegin(GL_QUADS);
            glTexCoord2f(0.0f, 0.0f); glVertex2f(2.8f, -1.1f); // moves BOTTOM EDGE UP or DOWN - stretches length of image
            glTexCoord2f(0.0f, 1.0f); glVertex2f(2.8f, -1.9f);
            glTexCoord2f(1.0f, 1.0f); glVertex2f(2.1f, -1.9f);
            glTexCoord2f(1.0f, 0.0f); glVertex2f(2.1f, -1.1f); // moves BOTTOM EDGE UP or DOWN - stretches length of image
            glEnd();
        }

这只是猜测,但您的代码中存在严重的设计问题,再加上内存泄漏,可能会导致您所描述的未定义结果。

首先,在imageLoaderOut()中,您从HDD读取每帧的所有纹理,将其转换为32bpp,并将数据发送到OpenGL。你从DrawGLScene开始调用它,这意味着你每帧都要调用它。这真是一种无效的做事方式。您不需要在每帧中加载资源。如果使用Initialize()函数,就可以一劳永逸地使用图形上的GL资源。

然后,我认为这里存在内存泄漏,因为您从未卸载bitmap60。当你加载每一帧时,可能每秒加载数千次,这些未释放的内存会累积起来。因此,一段时间后,出现了非常糟糕的情况,FreeImage拒绝加载纹理。

因此,可能的解决方案是:

  • 将资源加载移至应用程序的初始化阶段
  • 空闲泄漏资源:每个加载函数中的FreeImage_Unload(bitmap60)

希望能有所帮助。

问题似乎出现在glTexImage2D中。该手册可在此处找到:http://www.opengl.org/sdk/docs/man/xhtml/glTexImage2D.xml

特别是,他们说:

glTexImage2D为当前纹理单位指定二维纹理,使用glActiveTexture指定。

一旦您多次调用glTexImage2D,您似乎正在多次覆盖同一位置。