Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Page 1 of 2 12 LastLast
Results 1 to 10 of 17

Thread: Problems usin glTexSubImage2D and window resize...

  1. #1
    Junior Member Newbie
    Join Date
    May 2010
    Posts
    10

    Problems usin glTexSubImage2D and window resize...

    There's something fundamental I'm not doing right, because I'm having this problem in GLUT, OpenGL, and OpenCL. The basic idea is I'm using OpenGL for 2D raster graphics by rendering a quad with a texture. I use glTexSubImage2D to update the texture during Idle, and then during redraw I draw the quad with texture coordinates.

    Everything works fine unless I combine updating the texture with Window resize. (I can resize the window with no updates, or see my updates without resizing the window.) When I try both, as soon as a resize occurs, the texture rapidly fragments into rectangles and garbage throughout memory, as if the texture is lost. (The artifacts are not simple ones as you'd expect with incorrect pitch, etc.)

    I'll describe what I'm doing in GLUT, since it's the easiest, and I'm hoping someone can catch an error. This is in Mac OS-X Snow Leopard 10.6.3 / Xcode. I am VERY GRATEFUL for any help, as this has help me up for almost 2 years with no solution.

    (1) Initial setup before glutMainLoop(); I make a buffer for the texture. It's not a power of 2 size, but I've tried power of 2 sizes and got the same result:

    unsigned char* pucMyBuffer = malloc(w * h * 4);

    2) Then I set up the openGL context for it as so:
    // Create a new texture!
    glGenTextures(1, &gTex1ID);

    glBindTexture(GL_TEXTURE_2D,gTex1ID);
    glEnable( GL_TEXTURE_2D ); // Allow texturing!

    // This is needed!
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA,
    w,h, 0, GL_RGBA, GL_UNSIGNED_BYTE, pucMyBuffer);

    // Try to get Alpha to work:
    glEnable (GL_BLEND);
    glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    3) After entering glutMainLoop, I draw the window like this. Currently w and h are both 1.0 -> it depends whether I want
    to always fill the window with the texture or make the texture
    per pixel accurate:

    glBindTexture(GL_TEXTURE_2D,gTex1ID);

    glColor4f(1.0, 1.0, 1.0, fGlobalAlpha);
    glBegin(GL_QUADS);
    glTexCoord2f(0, 0); glVertex2f(0, 0);
    glTexCoord2f(1,0); glVertex2f(w, 0);
    glTexCoord2f(1,1); glVertex2f(w, h);
    glTexCoord2f(0, 1); glVertex2f(0, h);
    glEnd();

    glutSwapBuffers();

    4) I handle a resize like this. Again, the option depends
    on whether I want constant pixels or view

    //glViewport( 0, 0, w, h );
    glViewport( 0, 0, 1920, 1200 );
    glLoadIdentity();
    gluOrtho2D(0,1,0,1);

    glutPostRedisplay();
    glutPostWindowRedisplay(gMainWindowID);


    NOTE THAT EVERYTHING SO FAR WORKS PERFECTLY!

    5) And on the Idle call, I do this to keep the texture changing:
    (Note that the hard coded sizes were just part of my attempts to debug what was going on)

    // Do a loaded update:
    glTexSubImage2D(GL_TEXTURE_2D, 0, // MIP level
    0,0, // SrcX, SrcY
    1920,1200, // W,H
    GL_RGBA, GL_UNSIGNED_BYTE, pucMyBuffer);

    glutPostRedisplay();
    glutPostWindowRedisplay(gMainWindowID);

    This last step works as long as I don't resize, but it I resize after changing even 1 byte of the buffer, the display goes haywire.

    Any ideas are appreciated more than I can say. I am close to having to abandon the use of OpenGl after over a year of trying because I can find no programmer that knows anything about it.

    Thanks,
    - Jeff

  2. #2
    Junior Member Newbie
    Join Date
    May 2010
    Posts
    10

    Re: Problems usin glTexSubImage2D and window resize...

    I'll just add that my problem is that almost all OpenGL examples I've found make use of static textures and/or full screen mode. If anyone has a pointer to actual sample code using OpenGL for 2D display's, I'd be grateful. I'm also wondering - if glTexSubImage2D is somehow screwed up with window resizing, I wonder if I could just attempt to load up and attach a new texture with every window resize?

  3. #3
    Advanced Member Frequent Contributor
    Join Date
    Jan 2007
    Posts
    964

    Re: Problems usin glTexSubImage2D and window resize...

    I'd definitely create a new texture for each resize, but I'm not certain if your texture size is supposed to be the same dimensions as your window or not. Your code seems to assume that it isn't in one place but is in another, which I guess is the problem you have.

    You're also using a non-power-of-2 texture which might cause problems on some hardware, and - depending on your window size - might even exceed the max texture size allowed by your hardware.

  4. #4
    Member Regular Contributor
    Join Date
    Aug 2008
    Posts
    381

    Re: Problems usin glTexSubImage2D and window resize...

    If your pucMyBuffer stays a constant size, eg: 1920 x 1200, and then you are using
    Code :
    glTexSubImage2D(GL_TEXTURE_2D, 0, // MIP level
    0,0, // SrcX, SrcY
    W, H, 
    GL_RGBA, GL_UNSIGNED_BYTE, pucMyBuffer);
    where W <> 1920, you will be reading the data incorrectly from pucMyBuffer.
    glTexSubImage2D doesn't know that pucMyBuffer is a 2D array, it just treats it as a single block of memory, so it will load each row of the texture directly after the previous row.

    If you want a fixed size pucMyBuffer, you will need to inform OpenGL that it should skip the remaining unused bytes in pucMyBuffer:

    glPixelStorei(GL_UNPACK_ROW_LENGTH, 1920);

    then if you try loading a smaller image from pucMyBuffer with glTexSubImage2D, OpenGL will ignore the unused bytes at the end of each row.
    http://www.opengl.org/sdk/docs/man/x...PixelStore.xml

  5. #5
    Junior Member Newbie
    Join Date
    May 2010
    Posts
    10

    Re: Problems usin glTexSubImage2D and window resize...

    Guys, thanks so much for your ideas. I'll mess around some with glPixelStore and see if it helps. Honestly, though, despite this being aloppy example code, the width was always 1920 in my example. And the result I got was hard to explain -> massive flickering of white noise, etc. Maybe it needs to be a power of 2 texture (although I have tried that before).

    Another thing I noticed is that while I never got correct behavior, the resulting incorrect behavior depended very strongly on when/where I did the update in the overall scheme of things.

    I'm just curious -> can anyone on this list recommend a place where I could commission a programmer to write such a sample program? I've really lost all hope in being able to get this to work.

    Thanks,
    - Jeff

  6. #6
    Junior Member Newbie
    Join Date
    May 2010
    Posts
    10

    Re: Problems usin glTexSubImage2D and window resize...

    Guys, here's what I don't understand about all this. Why should the texture have any connection whatsoever to the window? Why should it need to be resized in any way? Although my goal is to make it stretch over the window, it's just a 3D texture on a quad. The quad's size is somewhere in the 3D world space.

    It seems like my texture should be able to be any resolution and just map to that quad, no matter what happens with the Window. Unless there's something about a window resize that destroys all the OpenGL context, so you have to load all the texture's over again.

  7. #7
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    2,882

    Re: Problems usin glTexSubImage2D and window resize...

    Quote Originally Posted by OpenGLHopeful
    Guys, here's what I don't understand about all this. Why should the texture have any connection whatsoever to the window? Why should it need to be resized in any way? Although my goal is to make it stretch over the window, it's just a 3D texture on a quad. The quad's size is somewhere in the 3D world space.

    It seems like my texture should be able to be any resolution and just map to that quad, no matter what happens with the Window.
    No, you're absolutely right. Which means the weird behavior on resize probably has something to do with a bug in how you handle resize.

    Whittle your program down to short test program, and somebody will probably be able to point out the error.

    For instance, I find it odd that you have no MatrixMode calls in your code. gluOrtho2D should be called when the PROJECTION matrix is active. And where are you initializing MODELVIEW to the identity. And if you are and seeing that you're passing 0,1,0,1 to gluOrtho2D, why are you sending verts down the pipe with coordinates 0..w, 0..h, where w,h = 1920x1200?

  8. #8
    Junior Member Newbie
    Join Date
    May 2010
    Posts
    10

    Re: Problems usin glTexSubImage2D and window resize...

    You've gotta deal. I'll try to get the simplest example possible. The trick is it always seems to work until I dynamically update the texture.

    Will get back to you folks.
    And thanks.

    - Jeff

  9. #9
    Junior Member Newbie
    Join Date
    May 2010
    Posts
    10

    Re: Problems usin glTexSubImage2D and window resize...

    Guys, I just got my first clue! I've been starting over with the most minimal GLUT project possible. And I what I found out is that if I do NOTHING AT ALL to draw the window, I get exactly the same visual artifacts!* Which means that my real issue is that my drawing routine is failing - maybe something as simple as I've set up the camera in a faulty way so I'm not seeing the quad.

    Here's what you can do to see what I'm seeing (abridged):

    Init: glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);

    void resize(int w, int h)
    {
    glViewport(0,0,(GLsizei)w,(GLsizei)h);
    glutPostRedisplay();
    }

    void redraw() // do nothing at all!
    {
    glutSwapBuffers();
    }

    * By the artifacts, it looks like either Snow Leopard or more likely the graphics card is actually tiling images for efficiency -> it looks like 128x128 blocks.

  10. #10
    Junior Member Newbie
    Join Date
    May 2010
    Posts
    10

    Re: Problems usin glTexSubImage2D and window resize...

    OK, I think I've solved the problem. It might be overkill. Could you more knowledgeable folk tell me if I really need to do everything? Unfortunately, performance is not great -> I'm averaging about 30 FPS (13-40fps) on a GeForce 8600GT. I wonder if this is a GLUT artifact, because when I don't update the texture I still only get (30-60fps), while on OpenGL using timer callbacks I get 300fps. Worse yet - it doesn't seem like the window itself is actually updating every time - the visual effect seems more like 5 FPS, and tearing is extreme.

    Anyway, here's what I now do:. For simplicity, the texture is now of fixed, constant size and is a RECTANGLE. Thanks so much for your encouragement!
    ====================
    Init:
    ====================
    // Create a new texture!
    glGenTextures(1, &amp;ImageID);

    // Use a GL_TEXTURE_RECTANGLE_ARB:
    glBindTexture(GL_TEXTURE_RECTANGLE_ARB,ImageID); // order?
    glEnable( GL_TEXTURE_RECTANGLE_ARB ); // Allow texturing!

    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_S, GL_CLAMP);
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_WRAP_T, GL_CLAMP);
    glTexParameterf(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);

    // Copy to the graphics card:
    glTexImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, GL_RGBA,
    IMAGE_W, IMAGE_H, 0, GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid *)ulImage);
    ====================
    Draw:
    ====================
    glMatrixMode (GL_PROJECTION); // needed?
    glLoadIdentity (); // needed?
    gluOrtho2D(0.0, 1.0, 1.0, 0.0);

    // Needed?
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // clear the surface
    glClear(GL_COLOR_BUFFER_BIT);

    // Draw the texture quad:
    glBindTexture(GL_TEXTURE_RECTANGLE_ARB,ImageID); // order?
    glEnable( GL_TEXTURE_RECTANGLE_ARB ); // Allow texturing!

    // Live Upload of latest image:
    CreateImage();

    glTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, // MipMap 0
    0,0,IMAGE_W,IMAGE_H,
    GL_RGBA, GL_UNSIGNED_BYTE, (const GLvoid *)ulImage);

    // Draw it! (texture rect is accessed by real coords)
    glColor4f(1.0, 1.0, 1.0, 1.0); // no alpha effect unless blending enabled
    glBegin(GL_QUADS);
    glTexCoord2f(0, 0); glVertex2f(0, 0);
    glTexCoord2f(IMAGE_W,0); glVertex2f(1, 0);
    glTexCoord2f(IMAGE_W,IMAGE_H); glVertex2f(1, 1);
    glTexCoord2f(0, IMAGE_H); glVertex2f(0, 1);
    glEnd();

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •