PDA

View Full Version : gBlendFunc behavior

rpenland
12-08-2003, 11:36 AM
I am new to OpenGL and have been going through some of the various book tutorials. Following the sample code for a simple blend, I wanted to take to RGBA bitmaps and combine them such that the left half would be from the one image and the right half would be from the other image. The code I am using is as follows:

#define checkImageWidth 256
#define checkImageHeight 256
GLubyte checkImage[checkImageHeight][checkImageWidth][4];
GLubyte checkImage2[checkImageHeight][checkImageWidth][4];
int gMainWindow = 0;

void makeCheckImage(void)
{
int i,j,c;

for(i = 0; i < checkImageHeight;i++)
{
for(j = 0; j < checkImageWidth; j++)
{
c = ((((i&0x8)==0)^((j&0x8))==0))*255;
checkImage[i][j][0] = (GLubyte) c;
checkImage[i][j][1] = (GLubyte) c;
checkImage[i][j][2] = (GLubyte) c;
if(j < checkImageWidth/2)
checkImage[i][j][4] = (GLubyte) 0x00;
else
checkImage[i][j][4] = (GLubyte) 0x255;
}
}
}
void makeCheckImage2(void)
{
int i,j,c;

for(i = 0; i < checkImageHeight;i++)
{
for(j = 0; j < checkImageWidth; j++)
{
c = ((((i&0x10)==0)^((j&0x10))==0))*255;
checkImage2[i][j][0] = (GLubyte) c;
checkImage2[i][j][1] = (GLubyte) c;
checkImage2[i][j][2] = (GLubyte) c;
if(j < checkImageWidth/2)
checkImage2[i][j][4] = (GLubyte) 0x255;
else
checkImage2[i][j][4] = (GLubyte) 0x00;
}
}
}
#pragma mark ---- GLUT callbacks ----

static void init (void)
{
glClearColor(0.0,0.0,0.0,0.0); /* Background recColor */
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
makeCheckImage();
makeCheckImage2();
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
}

void display(void)
{
glClear(GL_COLOR_BUFFER_BIT);
glRasterPos2i(0,0);
glEnable(GL_BLEND);
glBlendFunc(GL_ONE,GL_ZERO);
glDrawPixels(checkImageWidth,checkImageHeight,GL_R GBA,GL_UNSIGNED_BYTE,checkImage);
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
glDrawPixels(checkImageWidth,checkImageHeight,GL_R GBA,GL_UNSIGNED_BYTE,checkImage2);
glFlush();
}
void reshape(int w, int h)
{
glViewport(0,0,(GLsizei)w, (GLsizei) h);
glMatrixMode(GL_PROJECTION);
if(w <= h)
gluOrtho2D(0.0,1.0,0.0,1.0*(GLfloat)h/(GLfloat)w);
else
gluOrtho2D(0.0,1.0*(GLfloat)h/(GLfloat)w,0.0,1.0);
}
void keyboard(unsigned char key, int x, int y)
{
switch(key)
{
case '27': // help
exit(0);
break;
default:
break;
}
}

#pragma mark ---- main ----

int main (int argc, const char * argv[])
{
glutInit(&argc, (char **)argv);
glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); // non-stereo for main window
glutInitWindowPosition (300, 50);
glutInitWindowSize (checkImageWidth, checkImageHeight);
gMainWindow = glutCreateWindow("GLUT Basics");

init(); // standard GL init

glutReshapeFunc (reshape);
// glutKeyboardFunc (keyboard);
glutDisplayFunc (display);

glutMainLoop();
return 0;
}

All I see when I run this is a window filled entirely with the first image. Am I totally missing the boat here as to how to use this function?

Thanks,
Rob

dorbie
12-09-2003, 01:09 AM
The code looks good and as far as I can tell should work. I may have missed something though. I have not compiled and tested. Try this using Mesa instead of your card's drivers and see what you get. That's always handy for figuring if it's your problem or not.

sh
12-09-2003, 04:00 AM
glBlendFunc (GL_ONE, GL_ZERO);nullifies the effects of blending, so you might as well just call

glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); in your startup routine and use

glEnable (GL_BLEND); and

glDisable (GL_BLEND); as necessary.

The best way to do what you want is to render two textured quads with an orthographic projection matrix. The first is your first image with GL_BLEND disabled, and the second is the second image drawn overtop with GL_BLEND enabled, with alpha values set for one or more of its vertices.

dorbie
12-10-2003, 08:59 AM
None of these are errors in his algorithm.

They're reasonable suggestions for improving performance / tidying the code but his code should work as posted.