白色四元组将SDL_Surface转换为OPENGL_Texture

时间:2010-11-18 03:11:49

标签: opengl sdl

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

自我批评,我将我的代码分解得太多了,我喜欢把事情整理得井井有条,但是文件中可能有一些东西我没有太多...

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

可以使用我编写的类创建多维数据集,只需定义一个并为其指定文件名,它应该加载该纹理并在调用show函数时将其应用于多维数据集。

我让它部分使用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);

并且纹理准备就绪。

更新:

这是显示多维数据集的show方法

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函数

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           */

2 个答案:

答案 0 :(得分:1)

确保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

答案 1 :(得分:0)