【问题标题】:mingw OpenGL SDL shows only white texturesmingw OpenGL SDL 仅显示白色纹理
【发布时间】:2012-05-01 13:39:17
【问题描述】:

我尝试使用教程中提供的 Linux/SDL 版本使用 mingw for Windows 编译 Nehe (http://nehe.gamedev.net/tutorial/texture_mapping/12038/) 第 6 课。

立方体被绘制成纯白色而不是纹理。 (在win7和我的开发机器上测试过)

我可以确认纹理已被 SDL 正确加载,但显然没有加载到 OpenGL。

我也尝试生成随机噪声作为纹理(不使用 SDL_image 或 SDL_loadBMP),但 Windows 版本仍然不显示任何纹理。

我在 Ubuntu 下使用 Codeblocks 并通过本教程 http://wiki.codeblocks.org/index.php?title=Code::Blocks_and_Cross_Compilers 设置我的交叉编译器。

我认为这与我的编译方式有关,但无法确定错误的来源。

【问题讨论】:

  • 更新您的 GFX 卡驱动程序。
  • 没有帮助。另外:在 wine 上运行应该使用与正确呈现的本机 linux 客户端相同的驱动程序。
  • 您确定图片加载正确吗?你检查textureImage->w 是否正确?如果是,请同时贴出相关的渲染代码。
  • @Ben Ruijl:是的,图像可以很好地加载到 256x256 像素的 SDL 中。
  • -1 表示缺少相关信息。

标签: opengl mingw sdl cross-compiling


【解决方案1】:

我发现这个问题在谷歌上搜索同样的问题。花了一天时间才知道发生了什么。

问题是调整大小的方法可能会重新创建绘图区域左右,可能有很多程序使用同一个显卡,所以我的猜测是当这个调整大小的代码运行时,显卡会释放纹理。

在 resize 方法中重新加载纹理有助于(在我的项目中)没有尝试过第 6 课,但它遇到了相同的症状。

我将纹理原始数据放入缓存中,然后将它们重新加载到 openGL 中。

我希望这会有所帮助, 问候克里斯托弗。

【讨论】:

    【解决方案2】:

    glEnable(GL_TEXTURE_2D)。默认情况下禁用纹理。


    #include <SDL/SDL.h>
    #include <GL/glew.h>
    #include <GL/gl.h>
    #include <GL/glu.h>
    #include <wchar.h>
    #include <math.h>
    #include <SDL/SDL_image.h>
    
    #undef main
    
    static int scrWidth = 800;
    static int scrHeight = 600;
    
    int main(int argc, char** argv){
        SDL_Init(SDL_INIT_VIDEO);
    
        SDL_GL_SetAttribute(SDL_GL_RED_SIZE, 8);
        SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, 8);
        SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, 8);
        SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 16);
        SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
        SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, 0);
    
        if (SDL_SetVideoMode(scrWidth, scrHeight, 32, SDL_OPENGL) == 0){
            fprintf(stderr, "couldn't set mode %dx%d!\n", 640, 480);
            SDL_Quit();
            return -1;
        }
        glewInit();
        IMG_Init(IMG_INIT_PNG|IMG_INIT_JPG);
    
        SDL_ShowCursor(SDL_DISABLE);
    
        glClearColor(0.2f, 0.2f, 0.2f, 0.2f);
        glClearDepth(1.0f);
    
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_TEXTURE_2D);
    
        GLuint texId = 0;
        glGenTextures(1, &texId);
    
        glBindTexture(GL_TEXTURE_2D, texId);
    
    
        SDL_Surface* tex = IMG_Load("1.png");
    
        int texW = tex->w, texH = tex->h;
        SDL_LockSurface(tex);
    
        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    
        int bytesPerPixel = tex->format->BytesPerPixel;
    
        GLenum texFormat = GL_INVALID_ENUM, pixelFormat = GL_INVALID_ENUM;
    
        switch(bytesPerPixel){
            case(3):
                texFormat = GL_RGB;
                pixelFormat = texFormat;
                break;
            case(4):
                texFormat = GL_RGBA;
                pixelFormat = texFormat;
                break;
            default:
                fprintf(stderr, "invalid texture format: %d bytes per pixel", bytesPerPixel);
                SDL_FreeSurface(tex);
                SDL_Quit();
                return -1;
                break;
        }
    
        int expectedPitch = bytesPerPixel*tex->w;
        if (tex->pitch != expectedPitch){
            fprintf(stderr, "invalid surface pitch %d instead of %d", tex->pitch, expectedPitch);
            SDL_FreeSurface(tex);
            SDL_Quit();
            return -1;
        }
    
        glTexImage2D(GL_TEXTURE_2D, 0, texFormat, texW, texH, 0, pixelFormat, GL_UNSIGNED_BYTE, tex->pixels);
        GLenum err = glGetError();
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    
        SDL_UnlockSurface(tex);
    
        SDL_FreeSurface(tex);
    
    
        glBindTexture(GL_TEXTURE_2D, texId);
    
        bool running = true;
        while (running){
            SDL_Event event;
            if (SDL_PollEvent(&event)){
                switch(event.type){
                    case SDL_QUIT:
                        running = false;
                        break;
                };
            }
    
            glMatrixMode(GL_PROJECTION);
            glLoadIdentity();
            gluOrtho2D(0, scrWidth, scrHeight, 0);
    
            glMatrixMode(GL_MODELVIEW);
            glLoadIdentity();
    
            glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
    
            glBindTexture(GL_TEXTURE_2D, texId);
    
            glBegin(GL_TRIANGLE_FAN);
            glTexCoord2f(0, 0);
            glVertex2f(0, 0);
            glTexCoord2f(1, 0);
            glVertex2f((float)texW, 0);
            glTexCoord2f(1, 1);
            glVertex2f((float)texW, (float)texH);
            glTexCoord2f(0, 1);
            glVertex2f(0, (float)texH);
            glEnd();
    
            glDisable(GL_DEPTH_TEST);
    
            glFlush();
            SDL_GL_SwapBuffers();       
        }   
    
        glDeleteTextures(1, &texId);
    
        IMG_Quit();
        SDL_Quit();
        return 0;
    }
    

    【讨论】:

    • 从完全相同的源代码构建的 Linux 可以正常工作。我启用了 GL_TEXTURE_2D。
    • @Rock:“Linux 构建”这与您的问题无关。如果它有效,并不意味着它应该有效。 “我有 GL_TEXTURE_2D” 您的代码片段中没有 glEnable。您的代码也不会生成 mipmap。这可以使用 glGenerateMipmap、gluBuild2DMipmaps 或 glTexParameter(GL_GENERATE_MIPMAP) 来完成。你为什么不发布完整的小例子来证明你的问题?您当前的代码片段甚至没有任何渲染例程。
    • @Rock:看...从您或其他任何人那里逐段提取信息并不有趣。你不能简单地制作一个非常小的完整的 SDL 应用程序,使用 SDL_image 加载纹理并演示问题吗?这是一个"SDL draft application" 供您开始使用。另请阅读sscce.org 只需将您的渲染/初始化代码复制粘贴到 sn-p 中,确保它会产生您遇到的问题,然后在此处上传结果。 main.cpp 就足够了。这样我就可以抓住该死的东西,将其粘贴到我的编译器中并进行调试。
    • @Rock:如果没有完整的代码片段,我(以及几乎任何其他人)不得不求助于算命,这需要 50 倍的时间让我弄清楚可能出了什么问题(无限可能的情况),并且您需要更长的时间才能收到答案。
    • 从 Linux/SDL 版本的 NeHe.gamedev.net 中学习第 6 课并使用 mingw 编译。我只改变了上面所说的投影,再画了一个四边形。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多