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