将 SDL_Surface 转换为 OPENGL_Texture 的白色四边形

发布于 2024-10-03 18:39:26 字数 5556 浏览 1 评论 0原文

我正在尝试使用我在互联网上找到的一段代码将 SDL 表面转换为 openGL 纹理,经过几个小时的搜索,大多数似乎以相同的顺序使用相同的函数,所以我假设我'我正在做正确的事情。

自我批评,我把我的代码拆分得太多了,我喜欢让事情井井有条,但文件中可能埋藏着一些东西,我不会深入讨论......

长话短说,我的应用程序应该渲染 2 个立方体,旋转它们并允许移动其中一个。

可以使用我编写的类创建立方体,只需定义一个类并为其指定一个文件名,它应该加载该纹理并在调用显示函数时将其应用到立方体。

我让它部分与 SOIL 库一起工作,但我已将大量代码移至 SDL,并且我更喜欢使用 IMG_Load。

这是代码,

GLuint loadTexture(std::string filename)
{
    GLuint texture;
    if(SDL_Surface* surfaceTex = IMG_Load(filename.c_str()))
    {
        glPixelStorei(GL_UNPACK_ALIGNMENT,4);
        glGenTextures(1,&texture);
        glBindTexture(GL_TEXTURE_2D,texture);
        SDL_PixelFormat *format = surfaceTex->format;
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
        if (format->Amask)
        {
            gluBuild2DMipmaps(GL_TEXTURE_2D,4,surfaceTex->w,surfaceTex->h,GL_RGBA,GL_UNSIGNED_BYTE,surfaceTex->pixels);
        }
        else
        {
            gluBuild2DMipmaps(GL_TEXTURE_2D,3,surfaceTex->w,surfaceTex->h,GL_RGBA,GL_UNSIGNED_BYTE,surfaceTex->pixels);
        }
        SDL_FreeSurface(surfaceTex);
    }
    else
    {
        log("Loading texture failed!",true);
    }
    return texture;
}

我真的希望代码可以在项目之间移植,所以我可以说

Gluint Tex = loadTexture(filename);

纹理已经准备好了。

更新:

这是显示立方体

cubeTexture = loadTexture(filename);
glLoadIdentity();
glTranslatef(xPos,yPos,zPos);
xRotate = 1.0;
yRotate = 1.0;
zRotate = 1.0;
glRotatef(angle,xRotate,yRotate,zRotate);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, cubeTexture);
glBegin(GL_QUADS);
    /* Top face */
    glNormal3f(0.0f,0.0f,1.0f); /* Top face normal */
    glTexCoord2f(0.0f,  0.0f);  glVertex3f( Width,      Height,    -Depth); /* top right */
    glTexCoord2f(1.0f,  0.0f);  glVertex3f(-Width,      Height,    -Depth); /* top left */
    glTexCoord2f(1.0f,  1.0f);  glVertex3f(-Width,      Height,     Depth); /* bottom left */
    glTexCoord2f(0.0f,  1.0f);  glVertex3f( Width,      Height,     Depth); /* bottom right */
    /* Bottom face */
    glNormal3f(0.0f,0.0f,-1.0f); /* Bottom face normal */
    glTexCoord2f(1.0f,  0.0f);  glVertex3f( Width,     -Height,     Depth); /* top right */
    glTexCoord2f(1.0f,  1.0f);  glVertex3f(-Width,     -Height,     Depth); /* top left */
    glTexCoord2f(0.0f,  1.0f);  glVertex3f(-Width,     -Height,    -Depth); /* bottom left */
    glTexCoord2f(0.0f,  0.0f);  glVertex3f( Width,     -Height,    -Depth); /* bottom right */
    /* Front face */
    glNormal3f(0.0f,1.0f,0.0f); /* Front face normal */
    glTexCoord2f(0.0f,  1.0f);  glVertex3f( Width,      Height,     Depth); /* top right */
    glTexCoord2f(0.0f,  0.0f);  glVertex3f(-Width,      Height,     Depth); /* top left */
    glTexCoord2f(1.0f,  0.0f);  glVertex3f(-Width,     -Height,     Depth); /* bottom left */
    glTexCoord2f(1.0f,  1.0f);  glVertex3f( Width,     -Height,     Depth); /* bottom right */
    /* Back face */
    glNormal3f(0.0f,-1.0f,0.0f); /* Back face normal */
    glTexCoord2f(1.0f,  1.0f);  glVertex3f( Width,     -Height,    -Depth); /* top right */
    glTexCoord2f(0.0f,  1.0f);  glVertex3f(-Width,     -Height,    -Depth); /* top left */
    glTexCoord2f(0.0f,  0.0f);  glVertex3f(-Width,      Height,    -Depth); /* bottom left */
    glTexCoord2f(1.0f,  0.0f);  glVertex3f( Width,      Height,    -Depth); /* bottom right */
    /* Left face */
    glNormal3f(-1.0f,0.0f,0.0f); /* Left face normal */
    glTexCoord2f(1.0f,  0.0f);  glVertex3f(-Width,      Height,     Depth); /* top right */
    glTexCoord2f(1.0f,  1.0f);  glVertex3f(-Width,      Height,    -Depth); /* top left */
    glTexCoord2f(0.0f,  1.0f);  glVertex3f(-Width,     -Height,    -Depth); /* bottom left */
    glTexCoord2f(0.0f,  0.0f);  glVertex3f(-Width,     -Height,     Depth); /* bottom right */
    /* Right face */
    glNormal3f(1.0f,0.0f,0.0f); /* Right face normal */
    glTexCoord2f(0.0f,  0.0f);  glVertex3f( Width,      Height,    -Depth); /* top right */
    glTexCoord2f(1.0f,  0.0f);  glVertex3f( Width,      Height,     Depth); /* top left */
    glTexCoord2f(1.0f,  1.0f);  glVertex3f( Width,     -Height,     Depth); /* bottom left */
    glTexCoord2f(0.0f,  1.0f);  glVertex3f( Width,     -Height,    -Depth); /* bottom right */

glEnd();

和我的 GL_INIT 函数的 show 方法

glEnable(GL_TEXTURE_2D);            /* Enable Texture Mapping                           */
    glShadeModel(GL_SMOOTH);            /* Enable smooth shading                            */
    glClearColor(0.0f,0.0f,0.0f,0.0f);  /* Set the background black                         */
    glClearDepth(1.0f);                 /* Set the depth buffer up                          */
    glEnable(GL_DEPTH_TEST);            /* Set Depth testing up                             */
    glDepthFunc(GL_LEQUAL);             /* Sets the type of depth testing to Less or Equal  */
    glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);   /* Uses the nice perspective calcs  */
    glLightfv(GL_LIGHT1,GL_AMBIENT,LightAmbient);       /* Sets up the ambient light        */ //test
    glLightfv(GL_LIGHT1,GL_DIFFUSE,LightDiffuse);       /* Sets up the diffuse light        */ //test
    glLightfv(GL_LIGHT1,GL_POSITION,LightPosition);     /* Sets up the light position       */ //test
    glEnable(GL_LIGHT1);                                /* Enable the first light           */

I'm trying to convert a SDL surface to an openGL texture using a snippet of code I found lying around the internet, after many hours of searching, most seem to use the same functions in the same order, so I'm assuming i'm doing things right.

Self-Critisizing, i'm splitting up my code a little too much, i like to keep things organised, but there may be something buried in a file I don't go into much...

Long and short of it, my app is supposed to render 2 cubes, rotate them both and allow one to be moved.

Cubes can be created with a class I wrote, just define one and give it a filename, it should load that texture and apply it to the cube when the show function is called.

I had it working partially with the SOIL library, but i've moved a lot of code to SDL and I'd prefer to use IMG_Load instead.

Here's the code

GLuint loadTexture(std::string filename)
{
    GLuint texture;
    if(SDL_Surface* surfaceTex = IMG_Load(filename.c_str()))
    {
        glPixelStorei(GL_UNPACK_ALIGNMENT,4);
        glGenTextures(1,&texture);
        glBindTexture(GL_TEXTURE_2D,texture);
        SDL_PixelFormat *format = surfaceTex->format;
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
        if (format->Amask)
        {
            gluBuild2DMipmaps(GL_TEXTURE_2D,4,surfaceTex->w,surfaceTex->h,GL_RGBA,GL_UNSIGNED_BYTE,surfaceTex->pixels);
        }
        else
        {
            gluBuild2DMipmaps(GL_TEXTURE_2D,3,surfaceTex->w,surfaceTex->h,GL_RGBA,GL_UNSIGNED_BYTE,surfaceTex->pixels);
        }
        SDL_FreeSurface(surfaceTex);
    }
    else
    {
        log("Loading texture failed!",true);
    }
    return texture;
}

I really want the code to be portable between projects, so I can just say

Gluint Tex = loadTexture(filename);

and the texture is ready.

UPDATE:

Here's the show method for showing a cube

cubeTexture = loadTexture(filename);
glLoadIdentity();
glTranslatef(xPos,yPos,zPos);
xRotate = 1.0;
yRotate = 1.0;
zRotate = 1.0;
glRotatef(angle,xRotate,yRotate,zRotate);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, cubeTexture);
glBegin(GL_QUADS);
    /* Top face */
    glNormal3f(0.0f,0.0f,1.0f); /* Top face normal */
    glTexCoord2f(0.0f,  0.0f);  glVertex3f( Width,      Height,    -Depth); /* top right */
    glTexCoord2f(1.0f,  0.0f);  glVertex3f(-Width,      Height,    -Depth); /* top left */
    glTexCoord2f(1.0f,  1.0f);  glVertex3f(-Width,      Height,     Depth); /* bottom left */
    glTexCoord2f(0.0f,  1.0f);  glVertex3f( Width,      Height,     Depth); /* bottom right */
    /* Bottom face */
    glNormal3f(0.0f,0.0f,-1.0f); /* Bottom face normal */
    glTexCoord2f(1.0f,  0.0f);  glVertex3f( Width,     -Height,     Depth); /* top right */
    glTexCoord2f(1.0f,  1.0f);  glVertex3f(-Width,     -Height,     Depth); /* top left */
    glTexCoord2f(0.0f,  1.0f);  glVertex3f(-Width,     -Height,    -Depth); /* bottom left */
    glTexCoord2f(0.0f,  0.0f);  glVertex3f( Width,     -Height,    -Depth); /* bottom right */
    /* Front face */
    glNormal3f(0.0f,1.0f,0.0f); /* Front face normal */
    glTexCoord2f(0.0f,  1.0f);  glVertex3f( Width,      Height,     Depth); /* top right */
    glTexCoord2f(0.0f,  0.0f);  glVertex3f(-Width,      Height,     Depth); /* top left */
    glTexCoord2f(1.0f,  0.0f);  glVertex3f(-Width,     -Height,     Depth); /* bottom left */
    glTexCoord2f(1.0f,  1.0f);  glVertex3f( Width,     -Height,     Depth); /* bottom right */
    /* Back face */
    glNormal3f(0.0f,-1.0f,0.0f); /* Back face normal */
    glTexCoord2f(1.0f,  1.0f);  glVertex3f( Width,     -Height,    -Depth); /* top right */
    glTexCoord2f(0.0f,  1.0f);  glVertex3f(-Width,     -Height,    -Depth); /* top left */
    glTexCoord2f(0.0f,  0.0f);  glVertex3f(-Width,      Height,    -Depth); /* bottom left */
    glTexCoord2f(1.0f,  0.0f);  glVertex3f( Width,      Height,    -Depth); /* bottom right */
    /* Left face */
    glNormal3f(-1.0f,0.0f,0.0f); /* Left face normal */
    glTexCoord2f(1.0f,  0.0f);  glVertex3f(-Width,      Height,     Depth); /* top right */
    glTexCoord2f(1.0f,  1.0f);  glVertex3f(-Width,      Height,    -Depth); /* top left */
    glTexCoord2f(0.0f,  1.0f);  glVertex3f(-Width,     -Height,    -Depth); /* bottom left */
    glTexCoord2f(0.0f,  0.0f);  glVertex3f(-Width,     -Height,     Depth); /* bottom right */
    /* Right face */
    glNormal3f(1.0f,0.0f,0.0f); /* Right face normal */
    glTexCoord2f(0.0f,  0.0f);  glVertex3f( Width,      Height,    -Depth); /* top right */
    glTexCoord2f(1.0f,  0.0f);  glVertex3f( Width,      Height,     Depth); /* top left */
    glTexCoord2f(1.0f,  1.0f);  glVertex3f( Width,     -Height,     Depth); /* bottom left */
    glTexCoord2f(0.0f,  1.0f);  glVertex3f( Width,     -Height,    -Depth); /* bottom right */

glEnd();

and my GL_INIT function

glEnable(GL_TEXTURE_2D);            /* Enable Texture Mapping                           */
    glShadeModel(GL_SMOOTH);            /* Enable smooth shading                            */
    glClearColor(0.0f,0.0f,0.0f,0.0f);  /* Set the background black                         */
    glClearDepth(1.0f);                 /* Set the depth buffer up                          */
    glEnable(GL_DEPTH_TEST);            /* Set Depth testing up                             */
    glDepthFunc(GL_LEQUAL);             /* Sets the type of depth testing to Less or Equal  */
    glHint(GL_PERSPECTIVE_CORRECTION_HINT,GL_NICEST);   /* Uses the nice perspective calcs  */
    glLightfv(GL_LIGHT1,GL_AMBIENT,LightAmbient);       /* Sets up the ambient light        */ //test
    glLightfv(GL_LIGHT1,GL_DIFFUSE,LightDiffuse);       /* Sets up the diffuse light        */ //test
    glLightfv(GL_LIGHT1,GL_POSITION,LightPosition);     /* Sets up the light position       */ //test
    glEnable(GL_LIGHT1);                                /* Enable the first light           */

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦回梦里 2024-10-10 18:39:26

确保glEnable(GL_TEXTURE_2D)

此外,您的第二个 gluBuild2DMipmaps() 调用应采用 GL_RGB,而不是 GL_RGBA。否则,它会读取超过 SurfaceTex->pixels 末尾的内容。

试试这个:

#include <iostream>

#include <SDL.h>
#include <SDL_opengl.h>
#include <SDL_image.h>

using namespace std;

GLuint loadTexture(std::string filename)
{
    GLuint texture;
    if(SDL_Surface* surfaceTex = IMG_Load(filename.c_str()))
    {
        glPixelStorei(GL_UNPACK_ALIGNMENT,4);
        glGenTextures(1,&texture);
        glBindTexture(GL_TEXTURE_2D,texture);
        SDL_PixelFormat *format = surfaceTex->format;
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
        if (format->Amask)
        {
            gluBuild2DMipmaps(GL_TEXTURE_2D,4,surfaceTex->w,surfaceTex->h,GL_RGBA,GL_UNSIGNED_BYTE,surfaceTex->pixels);
        }
        else
        {
            gluBuild2DMipmaps(GL_TEXTURE_2D,3,surfaceTex->w,surfaceTex->h,GL_RGB,GL_UNSIGNED_BYTE,surfaceTex->pixels);
        }
        SDL_FreeSurface(surfaceTex);
    }
    else
    {
        return 0;
    }
    return texture;
}


int main(int argc, char* argv[])
{
    _putenv("SDL_VIDEO_CENTERED=1"); 

    SDL_Init(SDL_INIT_EVERYTHING); 

    int win_w = 800;
    int win_h = 600;
    SDL_Surface* display = SDL_SetVideoMode(win_w, win_h, 32, SDL_OPENGL);

    GLuint tex = loadTexture("concrete.png");

    bool running = true;
    while( running )
    {
        // handle all pending events
        SDL_Event event;
        while( SDL_PollEvent(&event) )
        {
            switch (event.type)
            {
                case SDL_KEYDOWN:
                    if( event.key.keysym.sym == SDLK_ESCAPE ) 
                        running = false;
                    break;
                case SDL_QUIT:
                    running = false;
                    break;
                default:
                    break;
            }
        }

        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

        glMatrixMode(GL_PROJECTION); 
        glLoadIdentity();
        glOrtho(0, win_w, 0, win_h, -10.0, 10.0);
        glMatrixMode(GL_MODELVIEW); 
        glLoadIdentity();

        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, tex);

        glPushMatrix();
        glScalef(200,200,200);
        glBegin(GL_TRIANGLES);
        glTexCoord2f(0,0);
        glVertex2f(0,0);
        glTexCoord2f(1,0);
        glVertex2f(1,0);
        glTexCoord2f(1,1);
        glVertex2f(1,1);
        glEnd();
        glPopMatrix();

        SDL_GL_SwapBuffers();
        SDL_Delay( 1 );
    }

    SDL_Quit();

    return 0;
}

concrete.png

concrete.png

Make sure to glEnable(GL_TEXTURE_2D).

Also, your second gluBuild2DMipmaps() call should take GL_RGB, not GL_RGBA. Otherwise it reads off past the end of surfaceTex->pixels.

Try this:

#include <iostream>

#include <SDL.h>
#include <SDL_opengl.h>
#include <SDL_image.h>

using namespace std;

GLuint loadTexture(std::string filename)
{
    GLuint texture;
    if(SDL_Surface* surfaceTex = IMG_Load(filename.c_str()))
    {
        glPixelStorei(GL_UNPACK_ALIGNMENT,4);
        glGenTextures(1,&texture);
        glBindTexture(GL_TEXTURE_2D,texture);
        SDL_PixelFormat *format = surfaceTex->format;
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
        if (format->Amask)
        {
            gluBuild2DMipmaps(GL_TEXTURE_2D,4,surfaceTex->w,surfaceTex->h,GL_RGBA,GL_UNSIGNED_BYTE,surfaceTex->pixels);
        }
        else
        {
            gluBuild2DMipmaps(GL_TEXTURE_2D,3,surfaceTex->w,surfaceTex->h,GL_RGB,GL_UNSIGNED_BYTE,surfaceTex->pixels);
        }
        SDL_FreeSurface(surfaceTex);
    }
    else
    {
        return 0;
    }
    return texture;
}


int main(int argc, char* argv[])
{
    _putenv("SDL_VIDEO_CENTERED=1"); 

    SDL_Init(SDL_INIT_EVERYTHING); 

    int win_w = 800;
    int win_h = 600;
    SDL_Surface* display = SDL_SetVideoMode(win_w, win_h, 32, SDL_OPENGL);

    GLuint tex = loadTexture("concrete.png");

    bool running = true;
    while( running )
    {
        // handle all pending events
        SDL_Event event;
        while( SDL_PollEvent(&event) )
        {
            switch (event.type)
            {
                case SDL_KEYDOWN:
                    if( event.key.keysym.sym == SDLK_ESCAPE ) 
                        running = false;
                    break;
                case SDL_QUIT:
                    running = false;
                    break;
                default:
                    break;
            }
        }

        glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 

        glMatrixMode(GL_PROJECTION); 
        glLoadIdentity();
        glOrtho(0, win_w, 0, win_h, -10.0, 10.0);
        glMatrixMode(GL_MODELVIEW); 
        glLoadIdentity();

        glEnable(GL_TEXTURE_2D);
        glBindTexture(GL_TEXTURE_2D, tex);

        glPushMatrix();
        glScalef(200,200,200);
        glBegin(GL_TRIANGLES);
        glTexCoord2f(0,0);
        glVertex2f(0,0);
        glTexCoord2f(1,0);
        glVertex2f(1,0);
        glTexCoord2f(1,1);
        glVertex2f(1,1);
        glEnd();
        glPopMatrix();

        SDL_GL_SwapBuffers();
        SDL_Delay( 1 );
    }

    SDL_Quit();

    return 0;
}

concrete.png:

concrete.png

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文