Click here to Skip to main content
14,334,974 members
Rate this:
Please Sign up or sign in to vote.
See more:
I drew a circle using opengl in MFC, and now i want to read that texture and store it in a byte array. How to do that?

What I have tried:

I drew the circle and tried to store the texture using below code, but it doesnt work

void OverlayDisplayDlg::OnBnClickedCircleRadio()
{
    GLfloat glRadius = 0.5f;

    glClear( GL_COLOR_BUFFER_BIT );
    glMatrixMode( GL_MODELVIEW );
    glLoadIdentity();
    glEnable( GL_TEXTURE_2D );
    glGenTextures( 2, &m_glTexture[1] );
    glBindTexture( GL_TEXTURE_2D, m_glTexture[1] );
    glBegin(GL_TRIANGLE_FAN);
    glColor3f( 1,1,0 );
    glVertex2d( 0, 0 );
    int nSegments = 100;
    GLfloat glAngle ;

    for( int nIndex = 0 ;nIndex <= nSegments; nIndex++ )
    {
        glAngle = ( nIndex* 2.0f * PI )/ nSegments;
        glVertex2d( cos( glAngle ) * glRadius , sin( glAngle ) * glRadius );
    }
    glEnd();
    glDisable( GL_TEXTURE_2D);
    glGetTexLevelParameterfv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &m_glTextureWidth );
    glGetTexLevelParameterfv( GL_TEXTURE_2D, 0, GL_TEXTURE_HEIGHT, &m_glTextureHeight );
    m_pbyImageData1 = new BYTE[ 4 * ( int )m_glTextureWidth * ( int )m_glTextureHeight ];
    //glGetTexImage( GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, m_pbyImageData1 );
    glReadBuffer( GL_BACK );
    glReadPixels( 0, 0, m_glTextureWidth, m_glTextureHeight, GL_RGBA, GL_UNSIGNED_BYTE, m_pbyImageData1 );
    SwapBuffers( m_hDeviceContextDC );
}


m_pbyImageData1 is a byte array . Please help me..
Posted
Updated 18-Apr-16 14:49pm
v2
Rate this:
Please Sign up or sign in to vote.

Solution 1

glGetTexLevelParameterfv <= That returns a float value :-)

You want the pixels for glReadPixels so integer version please ... so glGetTexLevelParameteriv.

Thats why you were having to cast to int and if you had of debugged the sizes would have been tiny. Use you debugger that is what it is there for.

Next be careful with the multiply you can be multiplying big integers so upcast to a long
m_pbyImageData1 = new BYTE[ 4 * (long)m_glTextureWidth * (long)m_glTextureHeight ];

Do you really want GL_BACK??

Dont forget to free the memory allocation when you are done
   
v3
Comments
Member 10536430 18-Apr-16 1:45am
   
glGetTexLevelParameteriv( GL_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &m_glTextureWidth );
returning 0 . Why
leon de boer 18-Apr-16 4:26am
   
Retrieve the error from the glGetError function and see what it says.

If you are still using GL_LUMINANCE I might guess the format is problematic. I don't use that format ever so it's a guess but the error return will shed some light.

I Looked at your code above again and don't you just want the display window screenwidth and screenheight not the texture width anyhow?
If you aren't after the whole scene you probably need to explain more.

I mean as an alternative I would just use the Win32 API make a Memory DC as a DIB section, swap the OpenGL render context onto the memory DC, and then use the DIB section for a standard windows save.
Member 10536430 18-Apr-16 10:24am
   
Thanks a lot. I got the result, instead of using m_glTextureWidth , i used another values for width n height and the error was solved. Now my problem is when i try to display that byte array, i,m getting the image along with a background.
I used the below code

BYTE* pbyNewImageData = NULL;
pbyNewImageData = new BYTE[ CIRCLEWIDTH * CIRCLEHEIGHT * 3];
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glEnable( GL_TEXTURE_2D );
glGenTextures( 1, &m_glTexture[1] );
glBindTexture( GL_TEXTURE_2D, m_glTexture[1] );
glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ); // Select modulate to mix texture with color for shading
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); // When texture area is small, bilinear filter the closest mipmap
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); // When texture area is large, bilinear filter the original
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ); // The texture wraps over at the edges (repeat)
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, CIRCLEWIDTH, CIRCLEHEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, pbyNewImageData );
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, m_glTexture[1] );
glBegin( GL_QUADS );
glTexCoord2d( 0.0,0.0 );
glVertex2f( -0.8f, -0.8f );
glTexCoord2d( 1.0,0.0 );
glVertex2f( 0.8f, -0.8f );
glTexCoord2d( 1.0,1.0 );
glVertex2f( 0.8f, 0.8f );
glTexCoord2d( 0.0,1.0 );
glVertex2f( -0.8f, 0.8f );
glEnd();
SwapBuffers( m_hDeviceContextDC );
glDisable( GL_TEXTURE_2D );
delete[] pbyNewImageData;
Member 10536430 18-Apr-16 10:35am
   
const int CIRCLEWIDTH = 700;
const int CIRCLEHEIGHT = 500;
const int CIRCLEPIXEL = 3;
leon de boer 18-Apr-16 15:04pm
   
You lost me that code will just put out blank or random noise?
Can I also ask what is all the enable/disable glEnable(GL_TEXTURE_2D) about?
You also seem to be missing glLoadIdentity() after glClear.

I will walk thru your code .. I will do it as a new reply so I can use advanced editing
Rate this:
Please Sign up or sign in to vote.

Solution 2

This is what you code does a far as I can work out .. I would think you either get junk or a blank area using that code.

glEnable( GL_TEXTURE_2D ) and disable is deprecated and I tried a quick search and the most common answer was it does nothing even if implemented. Never used it and no idea what it does.

BYTE* pbyNewImageData = NULL;
pbyNewImageData = new BYTE[ CIRCLEWIDTH * CIRCLEHEIGHT * 3];  // Allocate buffer 

// The allocated buffer contains zeros or random rubbish depending on mode
 
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // Yep clear GL buffers

glEnable( GL_TEXTURE_2D );  // ** I have no idea what this does

glGenTextures( 1, &m_glTexture[1] );                   // Generate a texture
glBindTexture( GL_TEXTURE_2D, m_glTexture[1] );        // Bind that texture to a 2D
glColorMaterial( GL_FRONT, GL_AMBIENT_AND_DIFFUSE );   // Use the lights/materials
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT );

// Next line puts zeros or random image buffer data to texture .. UMMM Okay 
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, 
   CIRCLEWIDTH, CIRCLEHEIGHT, 0, GL_RGB, GL_UNSIGNED_BYTE, pbyNewImageData );

glEnable( GL_TEXTURE_2D );  // ** I have no idea what this does

glBindTexture( GL_TEXTURE_2D, m_glTexture[1] );  // Bind the texture again :-) 

// Standard draw the texture onto faces
glBegin( GL_QUADS );
glTexCoord2d( 0.0,0.0 );
glVertex2f( -0.8f, -0.8f );
glTexCoord2d( 1.0,0.0 );
glVertex2f( 0.8f, -0.8f );
glTexCoord2d( 1.0,1.0 );
glVertex2f( 0.8f, 0.8f );
glTexCoord2d( 0.0,1.0 );
glVertex2f( -0.8f, 0.8f );
glEnd();

SwapBuffers( m_hDeviceContextDC );  // Resultant image to Dc probably screen

glDisable( GL_TEXTURE_2D );         // ** No idea what this does

delete[] pbyNewImageData;   // Delete our array that had zeros or junk
   
v4
Comments
Member 10536430 19-Apr-16 1:23am
   
Thanks a lot for your valuable comments. I removed the unwanted lines and then replaced glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) this line with glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE ); and my issue is solved. Thanks a lot for spending your valuable time in solving the issue.
Member 10536430 20-Apr-16 3:11am
   
can you please help me in solving http://www.codeproject.com/Questions/1094584/Display-opengl-texture-in-left-and-right-plane-in

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)




CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100