Results 1 to 7 of 7

Thread: using glCopyTexImage2D

  1. #1
    Junior Member
    Join Date
    May 2008
    Posts
    4

    using glCopyTexImage2D

    I've done alot of searching and trial/error, can't seem to figure this out, so here it goes...

    What I am trying to be able to do is to take whatever was last on the screen (currently showing on the screen) and save it as a texture so I can do whatever I want with it. All my attempts to copy it to a texture have failed so far.

    Here is a code snippet that I am using to try and create the texture:

    Code :
            glGenTextures(1, &screenTexture);
            glEnable(GL_TEXTURE_2D);  
            glBindTexture(GL_TEXTURE_2D, screenTexture);      
            glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);       
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
            glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
            glCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 0, 0, 256, 256, 0);

    That is initiated by a button press. Then what I do is render it to one side of a cube. The other 3 sides has textures that I have loaded from a file, and I use the same code to try and render this texture as I do with the other textures. Here is the code I call to render each side of the cube

    Code :
    void DrawQuad(float x1, float y1, float x2, float y2, float z1, float z2, float fWrapCount, GLuint uiTexture)
    {
     
     
    	// Use the given texture
    	glBindTexture(GL_TEXTURE_2D, uiTexture);
     
     
    	// Pass the vertex data
    	VERTTYPE afVertices[] = {f2vt(x1),f2vt(y1),f2vt(z1), f2vt(x2),f2vt(y1),f2vt(z2), f2vt(x1),f2vt(y2),f2vt(z1), f2vt(x2),f2vt(y2),f2vt(z2)};
    	glEnableClientState(GL_VERTEX_ARRAY);
    	glVertexPointer(3,VERTTYPEENUM,0,afVertices);
     
    	// Pass the texture coordinates data
    	VERTTYPE afTexCoord[] = {f2vt(0),f2vt(0), f2vt(fWrapCount),f2vt(0), f2vt(0),f2vt(fWrapCount), f2vt(fWrapCount),f2vt(fWrapCount)};
    	glEnableClientState(GL_TEXTURE_COORD_ARRAY);
    	glTexCoordPointer(2,VERTTYPEENUM,0,afTexCoord);
     
    	// Draws an indexed triangle list
    	unsigned short aIndices[] = {0,1,2, 2,1,3};
    	glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, aIndices);
    }

    Like I said, the textures that I load from a file work fine, but the screenshot texture...not so much. It creates some garbage on the screen so I know it is doing something, but definitely not what I want it to.

    Any ideas on where I am going wrong?

  2. #2
    Junior Member
    Join Date
    May 2008
    Posts
    4

    Re: using glCopyTexImage2D

    as a follow up to this, it appears that all that is copied is the clear color of the scene. So if I change the clearColor to red or blue, etc. I end up with one side of the cube being that color, that isn't what I want obviously but maybe it will help understand my problem.

  3. #3
    Senior Member
    Join Date
    May 2006
    Posts
    353

    Re: using glCopyTexImage2D

    At what point are you calling glCopyTexImage2D? Note that it reads from the back buffer of the current context read surface, not the front buffer buffer (which is currently displayed on the screen).
    Georg Kolling, Imagination Technologies
    Please ask questions specific to PowerVR hardware or SDKs on the PowerVR Insider Forum
    DevTech@imgtec.com | http://www.powervrinsider.com

  4. #4
    Junior Member
    Join Date
    May 2008
    Posts
    4

    Re: using glCopyTexImage2D

    That makes more sense now, if I call it at the end of my rendering instead of the middle I do get something recognizable. Thanks a lot for pointing that out.

    However, my end goal is to be able to take whatever was on the screen before my application began running and do a transition of some sort. How is it possible to get whatever is currently on the screen (even if your application did not render it) and turn it into a texture?

  5. #5
    Senior Member
    Join Date
    May 2006
    Posts
    353

    Re: using glCopyTexImage2D

    Quote Originally Posted by JTScott
    However, my end goal is to be able to take whatever was on the screen before my application began running and do a transition of some sort. How is it possible to get whatever is currently on the screen (even if your application did not render it) and turn it into a texture?
    That depends on the platform, OS, and window system you're targeting. Some might grant you access to the framebuffer, others don't.
    Georg Kolling, Imagination Technologies
    Please ask questions specific to PowerVR hardware or SDKs on the PowerVR Insider Forum
    DevTech@imgtec.com | http://www.powervrinsider.com

  6. #6
    Junior Member
    Join Date
    May 2008
    Posts
    4

    Re: using glCopyTexImage2D

    Currently experimenting on a device with Windows Mobile 6 Standard

  7. #7
    Junior Member
    Join Date
    Dec 2008
    Posts
    1

    Re: using glCopyTexImage2D

    I am investigating this exact same issue. I read in a tutorial that OpenGL can't grab/put anything outside its rendering area. If you get the screen pixel data using GDI:

    HDC hScreenDC = CreateDC(NULL, NULL, NULL, NULL);
    HDC hMemoryDC = CreateCompatibleDC(NULL);

    int Width = GetSystemMetrics(SM_CXSCREEN) ;
    int Height = GetSystemMetrics(SM_CYSCREEN) ;

    //Not sure if we need all the info, This will tell the system what format we want the pixels to be in
    BITMAPINFO bmi;
    ZeroMemory( &bmi.bmiHeader, sizeof(BITMAPINFOHEADER) );
    bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmi.bmiHeader.biWidth = Width;
    bmi.bmiHeader.biHeight = Height;
    bmi.bmiHeader.biSizeImage = (Width * Height) * 3;
    bmi.bmiHeader.biPlanes = 1;
    bmi.bmiHeader.biCompression = BI_RGB;
    bmi.bmiHeader.biBitCount = 24;

    //All we are really interested in
    DWORD* pBitmapBits;

    BITMAPFILEHEADER hdr;
    ////create bitmap from buffer...
    int nColors = 0;

    //// Fill in the fields of the file header
    hdr.bfType = ((WORD) ('M' << 8 ) | 'B'); // is always "BM" for bitmap
    hdr.bfSize = 0;//GlobalSize (hDIB) + sizeof( hdr );
    hdr.bfReserved1 = 0;
    hdr.bfReserved2 = 0;
    hdr.bfOffBits = (DWORD) (sizeof( hdr ) + sizeof(BITMAPINFOHEADER) + nColors * sizeof(RGBQUAD));

    //sloppy bad way of grabbing the bits. You could probably use a format specific bitmap here
    HBITMAP hNewBitmap = CreateDIBSection( hMemoryDC,
    &bmi,
    DIB_RGB_COLORS,
    (void**)&pBitmapBits,
    NULL,
    0
    );

    HBITMAP hOldBitmap = static_cast<HBITMAP>(SelectObject(hMemoryDC, hNewBitmap));

    //copy the on screen bitmap to our DC
    BOOL bitBltSuccess = BitBlt(hMemoryDC, 0, 0, Width, Height, hScreenDC, X1, Y1, SRCCOPY);

    then pass the pointer pBitmapBits to glTexImage2D() which will "render this texture on all enabled surfaces" (http://opengles.net/opengles/sdk/1.1/do ... mage2D.xml)

    I am really newbie to opengl(today) so this might not make sense. But I would also like to accomplish the same goal. If this helps or you can help me, please let me in on the final product

Posting Permissions

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