开发者

White quad converting SDL_Surface to OPENGL_Texture

开发者 https://www.devze.com 2023-01-25 10:03 出处:网络
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 orde

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 */
    glTe开发者_开发知识库xCoord2f(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           */


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:

White quad converting SDL_Surface to OPENGL_Texture


Try glPixelStorei(GL_UNPACK_ALIGNMENT,1).

Avoid gluBuild2DMipmaps().

0

精彩评论

暂无评论...
验证码 换一张
取 消