screen capture

i want to capture the opengl screen and save it with alpha channel.i m reading the pixels using glReadPixel . i m trying to write in bmp format , but the saved image isnt transparent . my code is as follows :-

//code

#include <Windows.h>
#include <gl/glut.h>
#include <gl/gl.h>
#include <gl/glu.h>
#include <cstdio>

#include <IL/ilu.h>
#include <IL/ilut.h>
#include <IL/il.h>

#define NUM_TEXTURE 2 //number of video textures

#define CAPTURE // define when u want to capture image
#define SHOW // define when u want to show the window
#define ROTATE // define when u want pic to rotate
//#define REFLECTION // define when u want to see reflection

GLfloat theta = -45.0;
GLuint texture[NUM_TEXTURE];
GLuint floorTexture;
BYTE * currentData;

void WriteBmp(char* name,int W,int H,int Bpp,int* data);
void cpatureImage();
void WriteBmp(char* name,int W,int H,int Bpp,int* data);
bool LoadTextureBMP(LPTSTR szFileName, GLuint *texpt , int repeat);
void init(void);
void display(void);
void reshape(int w, int h);
void drawFloor();
void WritePng();

void captureImage() //captures the current image and fill it in current data
{
glReadBuffer(GL_FRONT);
currentData=(BYTE )malloc(640360*4);
glPixelStorei(GL_PACK_ALIGNMENT, 4);
glReadPixels(0,0,640,360,GL_BGRA_EXT,GL_UNSIGNED_BYTE,currentData);
WriteBmp(“result.bmp”,640,360,32,(int *)currentData);
}

void WriteBmp(char* name,int W,int H,int Bpp,int* data) //writes the data into a .bmp image and saves it
{
BITMAPINFO Bmi={0};
Bmi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
Bmi.bmiHeader.biWidth = W;
Bmi.bmiHeader.biHeight = H;
Bmi.bmiHeader.biPlanes = 1;
Bmi.bmiHeader.biBitCount = Bpp;
Bmi.bmiHeader.biCompression = BI_RGB;
Bmi.bmiHeader.biSizeImage = WHBpp/8;

FILE* image = fopen (name,“wb”);
if(image==0)
return;
int h = abs(Bmi.bmiHeader.biHeight);
int w = abs(Bmi.bmiHeader.biWidth);
Bmi.bmiHeader.biHeight=h;
Bmi.bmiHeader.biWidth=w;
int sz = Bmi.bmiHeader.biSizeImage;

BITMAPFILEHEADER bfh;
bfh.bfType=(‘M’<<8)+‘B’;
bfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
bfh.bfSize=sz+bfh.bfOffBits;
bfh.bfReserved1=0;
bfh.bfReserved2=0;

fwrite(&bfh,sizeof(bfh),1,image);
fwrite(&Bmi.bmiHeader,sizeof(BITMAPINFOHEADER),1,image);
fwrite(data,sz,1,image);
fclose(image);
}

bool LoadTextureBMP(LPTSTR szFileName, GLuint *texpt , int repeat=1) //reads 24 bits bitmap made by windows
{
HBITMAP hBMP;
BITMAP BMP;
glGenTextures(1, texpt);
hBMP=(HBITMAP)LoadImage(GetModuleHandle(NULL), szFileName, IMAGE_BITMAP, 0, 0, LR_CREATEDIBSECTION | LR_LOADFROMFILE );
if (!hBMP)
return FALSE;

GetObject(hBMP, sizeof(BMP), &BMP);									
glBindTexture( GL_TEXTURE_2D, *texpt );
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
               GL_LINEAR_MIPMAP_NEAREST );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST );

glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S,repeat?GL_CLAMP:GL_REPEAT );
glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T,repeat?GL_CLAMP:GL_REPEAT );
gluBuild2DMipmaps( GL_TEXTURE_2D, 3, BMP.bmWidth,
	BMP.bmHeight, GL_BGR_EXT, GL_UNSIGNED_BYTE, BMP.bmBits );
DeleteObject(hBMP);													

return TRUE;														

}

void init(void) // initializer function
{
glClearColor (0.05, 0.05, 0.05, 0.0);
glBlendFunc (GL_SRC_ALPHA_SATURATE, GL_ONE);
glColor3f(1.0,1.0,1.0);
glShadeModel(GL_SMOOTH);
glEnable(GL_SCISSOR_TEST);
glScissor(0,13,640,340);
}

void drawFloor() // Draws reflective surface for Frame 1 Presenter Frame
{
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, floorTexture);

glPushMatrix(); // Draw the front side of the floor
glTranslatef(0.0f,-1.25f,0.0f);
glRotatef(90.0,1.0f,0.0f,0.0f);
glTranslatef(0.0f,1.25f,0.0f);

glColor3f(1.0,1.0,1.0);

glBegin(GL_POLYGON);
glTexCoord2d(0.0,0.0); glVertex2d(-2.00,-1.25);
glTexCoord2d(1.0,0.0); glVertex2d(4.0,-1.25);
glTexCoord2d(1.0,1.0); glVertex2d(4.0,+2.5);
glTexCoord2d(0.0,1.0); glVertex2d(-2.00,+2.5);
glEnd();

glPopMatrix();

glPushMatrix(); //Draw the back side of the floor
glTranslatef(0.0f,-1.25f,0.0f);
glRotatef(-90.0,1.0f,0.0f,0.0f);
glTranslatef(0.0f,1.25f,0.0f);

glColor3f(1.0,1.0,1.0);

glBegin(GL_POLYGON);
glTexCoord2d(0.0,0.0); glVertex2d(-2.00,-1.25);
glTexCoord2d(1.0,0.0); glVertex2d(4.0,-1.25);
glTexCoord2d(1.0,1.0); glVertex2d(4.0,+3.5);
glTexCoord2d(0.0,1.0); glVertex2d(-2.00,+3.5);
glEnd();

glPopMatrix();
}

void display(void) //display function is called whenever image has to be redrawn
{
glClear (GL_COLOR_BUFFER_BIT);
glColor3f (1.0, 1.0, 1.0);
glLoadIdentity ();

gluLookAt (0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0);

glTranslatef(-1.0,0.0,-5.5);
glPushMatrix(); //Frame 1 Presenter Frame Start

glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, texture[0] );

glBegin(GL_POLYGON);

glTexCoord2d(0.0,0.0); glVertex2d(-1.00,-1.25);
glTexCoord2d(1.0,0.0); glVertex2d(0.0,-1.25);
glTexCoord2d(1.0,1.0); glVertex2d(0.0,+.75);
glTexCoord2d(0.0,1.0); glVertex2d(-1.00,+.75);

glEnd();

glPopMatrix(); //Frame 1 Presenter Frame Ends

glPushMatrix(); //Frame 2 Presentation Frame Start
glTranslatef(-0.05f,0.0f,0.0f);
glRotatef(theta,0.0f,1.0f,0.0f);
glTranslatef(0.05f,0.0f,0.0f);
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, texture[1] );

glBegin(GL_POLYGON);
glTexCoord2d(0.0,0.0); glVertex2d(0.05,-1.25);
glTexCoord2d(1.0,0.0); glVertex2d(+3.5,-1.25);
glTexCoord2d(1.0,1.0); glVertex2d(+3.5,+1.25);
glTexCoord2d(0.0,1.0); glVertex2d(0.05,+1.25);
glEnd();

glPopMatrix(); //Frame 2 Presentation Frame Ends

glColor4f(0.0,0.0,0.0,0.5);
//drawFloor();

glEnable(GL_BLEND);
glColor4f(1.0,1.0,1.0,1.0);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
#ifdef REFLECTION
glPushMatrix(); //Frame 1 Presenter Frame Reflection Start
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, texture[0] );
glTranslatef(0.0f,-1.25f,0.0f);
glRotatef(180.0,1.0f,0.0f,0.0f);
glTranslatef(0.0f,1.25f,0.0f);

glColor3f(1.0,1.0,1.0);

glBegin(GL_POLYGON);
glTexCoord2d(0.0,0.0); glVertex2d(-1.00,-1.25);
glTexCoord2d(1.0,0.0); glVertex2d(0.0,-1.25);
glTexCoord2d(1.0,1.0); glVertex2d(0.0,+.75);
glTexCoord2d(0.0,1.0); glVertex2d(-1.00,+.75);
glEnd();
glPopMatrix(); //Frame 1 Presenter Frame Reflection Ends
#endif

#ifdef REFLECTION
glPushMatrix(); //Frame 2 Presentation Frame Reflection Starts
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, texture[1] );
glTranslatef(-0.05f,0.0f,0.0f);
glRotatef(theta,0.0f,1.0f,0.0f);
glTranslatef(0.05f,0.0f,0.0f);

glTranslatef(0.0f,-1.25f,0.0f);
glRotatef(180.0,1.0f,0.0f,0.0f);
glTranslatef(0.0f,1.25f,0.0f);

glColor3f(1.0,1.0,1.0);

glBegin(GL_POLYGON);
glTexCoord2d(0.0,0.0); glVertex2d(0.05,-1.25);
glTexCoord2d(1.0,0.0); glVertex2d(+3.5,-1.25);
glTexCoord2d(1.0,1.0); glVertex2d(+3.5,+1.25);
glTexCoord2d(0.0,1.0); glVertex2d(0.05,+1.25);
glEnd();
glPopMatrix(); //Frame 2 Presentation Frame Reflection Ends
#endif REFLECTION
glBlendFunc (GL_SRC_ALPHA_SATURATE, GL_ONE);
glutSwapBuffers();
#ifdef CAPTURE
captureImage();
#endif
#ifdef ROTATE
if(theta> -50.0)
theta-=0.05;
glutPostRedisplay();
#endif

glFlush();

}

void reshape(int w, int h) // reshape function called whenever window size is changed
{
GLfloat ar= float(w)/h;
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
glFrustum (-1.0, 1.0, -1.0, 1.0, 5.0, 30.0);
glMatrixMode (GL_MODELVIEW);
glEnable (GL_BLEND);
glEnable (GL_POLYGON_SMOOTH);
}

int main(int argc, char** argv)
{
glutInit(&argc, argv);
glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGBA | GLUT_ALPHA | GLUT_DEPTH);
glutInitWindowSize (640, 360);
glutInitWindowPosition (0,0);
glutCreateWindow (argv[0]);
init ();
#ifdef SHOW
glutDisplayFunc(display);
glutReshapeFunc(reshape);
#endif
LoadTextureBMP(L"presenter.bmp",&texture[0],1);
LoadTextureBMP(L"thumbnail.bmp",&texture[1],1);
LoadTextureBMP(L"wood_texture.bmp",&floorTexture,0);
#ifndef SHOW
reshape(640,360);
display();
#endif
glutMainLoop();
return 0;
}

//code ends

bmp does not manage a fourth channel. Try tga, rgb, png…

i used devil and i m able to save the image as png . but even though i clear the window using alpha 0.0 the backgound is not transparent . how can i make the background transparent ??

http://www.opengl.org/resources/faq/technical/transparency.htm

i did not understand . can u explain it ?? why do i need to use blending ? i want to make background transparent and then draw some primitive on it(which i want to be opaque so no blending) . and then i want to save this image so that when i open it in any image viewer i see a image that only has the primitive .

Well, finally we could understand a bit more what you want to do. Try to explain exactly what you want to achieve. On your first posts, noone could understand that you wanted to do what you said on your last post.
And a hello, thanks is never too much :slight_smile:

Try something like this:


unsigned char data[4*width*height];
glClearColor (0,0,0,0);
glClear (GL_COLOR_BUFFER_BIT);
// draw your primitives
...
// get the image
glReadPixels (0,0,width,height,GL_RGBA,GL_UNSIGNED_BYTE,data);

// save data into png file

thanks for the help and thanks for pointing out that i wasnt saying thanks :slight_smile: . it works now . the only problem was that in glReadPixel i was giving GL_BGRA_EXT instead of GL_RGBA … thanks again …

Shouldn’t you be reading your format and type first?


        GLint readType;
        GLint readFormat;
        glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_TYPE, &readType);
        glGetIntegerv(GL_IMPLEMENTATION_COLOR_READ_FORMAT, &readFormat);

        glReadPixels(0, 0, backingWidth, backingHeight, readFormat, readType, buffer);

u can do it using this prog http://www.geovid.com/Screen_VidShot/, it’s very simple

WTF?