Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
639 views
in Technique[技术] by (71.8m points)

qt - Using QImage with OpenGL

I've very recently picked up Qt and am using it with OpenGL The thing though is that when moving my SDL code to Qt and changing the texture code to use QImage it stops working.

The image does load correctly, as shown through the error checking code.

Thanks!

P.S: Please don't suggest I use glDrawPixels, I need to fix the problem at hand. Some of the reasons for that being 1. slow 2. android (which this code may be running on eventually) is OpenGL ES and does not support glDrawPixels

Here's the code:

//original image
QImage img;
if(!img.load(":/star.png"))
{
    //loads correctly
    qWarning("ERROR LOADING IMAGE");
}

//array for holding texture ID
GLuint texture[1];

//get the OpenGL-friendly image
QImage GL_formatted_image;
GL_formatted_image = QGLWidget::convertToGLFormat(img);

//make sure its not null
if(GL_formatted_image.isNull())
    qWarning("IMAGE IS NULL");
else
    qWarning("IMAGE NOT NULL");

//generate the texture name
glGenTextures(1, texture);

//bind the texture ID
glBindTexture(GL_TEXTURE_2D, texture[0]);

//generate the texture
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, GL_formatted_image.width(),
              GL_formatted_image.height(),
              0, GL_RGBA, GL_UNSIGNED_BYTE, GL_formatted_image.bits() );

//texture parameters
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);



//draw the texture
glPushMatrix();
glTranslatef(-2.0f, 0.0f, 0.0f);
glColor3f(1.0f, 1.0f, 1.0f);
glBegin(GL_TRIANGLES);
    glVertex2f(1.0f, 0.0f);
 glTexCoord2f(1.0f, 0.0f);
    glVertex2f(0.0f, 1.0f);
 glTexCoord2f(0.0f, 1.0f);
    glVertex2f(0.0f, 0.0f);
 glTexCoord2f(0.0f, 0.0f);
glEnd();
glPopMatrix();

Here's the original texture loading function with SDL:

GLuint loadTexturewithSDL(const char* FILE, GLenum texture_format)
{
    GLuint texture;         // This is a handle to our texture object
    SDL_Surface *surface;   // This surface will tell us the details of the image
    GLint  nOfColors;



    if ( (surface = SDL_LoadBMP(FILE)) ) {

    // Check that the image's width is a power of 2
    if ( (surface->w & (surface->w - 1)) != 0 ) {
        printf("warning: image's width is not a power of 2
");
    }

    // Also check if the height is a power of 2
    if ( (surface->h & (surface->h - 1)) != 0 ) {
        printf("warning: image's height is not a power of 2
");
    }

        // get the number of channels in the SDL surface
        nOfColors = surface->format->BytesPerPixel;
        if (nOfColors == 4)     // contains an alpha channel
        {
                if (surface->format->Rmask == 0x000000ff)
                        texture_format = GL_RGBA;
                else
                        texture_format = GL_BGRA;
        } else if (nOfColors == 3)     // no alpha channel
        {
                if (surface->format->Rmask == 0x000000ff)
                        texture_format = GL_RGB;
                else
                        texture_format = GL_BGR;
        } else {
                printf("warning: the image is not truecolor..  this will probably break
");
                // this error should not go unhandled
        }

    // Have OpenGL generate a texture object handle for us
    glGenTextures( 1, &texture );

    // Bind the texture object
    glBindTexture( GL_TEXTURE_2D, texture );

    // Set the texture's stretching properties
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
        glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );

    // Edit the texture object's image data using the information SDL_Surface gives us
    glTexImage2D( GL_TEXTURE_2D, 0, nOfColors, surface->w, surface->h, 0,
                      texture_format, GL_UNSIGNED_BYTE, surface->pixels );
}
else {
    printf("SDL could not load image %s
", SDL_GetError());
    SDL_Quit();
    return 1;
}

// Free the SDL_Surface only if it was successfully created
if ( surface ) {
    SDL_FreeSurface( surface );
}

    return texture;
}
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

This is my solution for conversion from Qt to GL This also can work in reverse with little changes; Cheers -- Daimon

void Image::Convert32bitARGBtoRGBA()
{
    if(!isQtImage()) return;
    QImage& q = *(m_data->image);
    U32 count=0, max=(U32)(q.height()*q.width());
    U32* p = (U32*)(q.bits());
    U32 n;
    while( count<max )
    {
        n = p[count];   //n = ARGB
        p[count] =  0x00000000 |
                ((n<<8)  & 0x0000ff00) |
                ((n<<8)  & 0x00ff0000) |
                ((n<<8)  & 0xff000000) |
                ((n>>24) & 0x000000ff);
                // p[count] = RGBA
        count++;
    }
}

void Image::Convert32bitRGBAtoARGB()
{
    if(!isQtImage()) return;
    QImage& q = *(m_data->image);
    U32 count=0, max=(U32)(q.height()*q.width());
    U32* p = (U32*)(q.bits());
    U32 n;
    while( count<max )
    {
        n = p[count];   //n = RGBA
        p[count] =  0x00000000 |
                ((n>>8)  & 0x000000ff) |
                ((n>>8)  & 0x0000ff00) |
                ((n>>8)  & 0x00ff0000) |
                ((n<<24) & 0xff000000);
                // p[count] = ARGB
        count++;
    }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...