polygon edges and alpha blending

Started by
6 comments, last by Solias 19 years, 5 months ago
I'm new to OpenGl so i've been doing some simple experimenting to get the hang of it. Ive setup a single multitextured quad in OpenGL using triangle strips as my primitive type. Ive got blending turned on with GL_ONE_MINUS_SRC_ALPHA as my blending function. The polygons colour is white (1.0, 1.0, 1.0, 1.0) and I see an alpha blended white diagonal line show through my texture that is the edge of the two poly triangles that make up the quad. This white line only appears on my nVidia card however and does not appear on an ati card that i tested the application on. If I turn off alpha blending the white line disappears so i'm convinced it has to do with blending. My rendering states are set up like so: glClearColor(1.0, 1.0, 1.0, 0.0); glPointSize(5.0); glEnable(GL_POINT_SMOOTH); glEnable(GL_LINE_SMOOTH); glEnable(GL_POLYGON_SMOOTH); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glShadeModel(GL_SMOOTH); glDisable(GL_DEPTH_TEST); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); If anyone could shed some light on this most frustrating problem it would be most appreciated!
Advertisement
your background is white polygons are white and the line is white? i cant understand the prolem well. but it may be a problem with fixed points.
+-+-+-+-+-STR
I don't fully understand what you are doing here. Maybe post some more of the drawing code and possibly a screen shot of the bug. My first thought was that you might be using GL_CLAMP, however that causes a similar problem on ati cards while "working" on nvidia cards. It also only happens at the edge of the texture.

Ive hacked out the meat of the code that i was experiencing the problem on and have created a program with only the necissary code
which follows below. I'll try to get a screen shot of the problem in action but for now clearer description of the problem is:
Imaging a single square polygon. The polygon is textured with a simple blue gradiant texture. The texture looks fine except there is a diagonal white line running from the top right corner of the square to the bottom left corner of the square. This diagonal is not 'pure' white - although it is VERY noticable - it appears to be blended with the gradiant so that it is darker where the gradiant is darker and lighter where the gradiant is lighter. ( whew! a picture IS worth a thousand words!)
Ive experimented a little and found that if i set the glTexEnv parameter to GL_REPLACE it still occures?! The only way i can get the diagonal line to dissappear completely is to turn off blending.

This is extremely frustrating! Any help would be greatly appreciated.
*note that in the code below the cPNGImage class is a helper class i wrote to load png images. Ive left out the window creation code and such for brevity...
void PrepareScene(){	glClear(GL_COLOR_BUFFER_BIT);	glClearDepth(1.0);	glLoadIdentity();}void Render(){	gluLookAt(0.0, 0.0, 1.0, 0.0, 0.0, -1.0, 0.0, 1.0, 0.0);	glColor4f(1.0,1.0,1.0,1.0);	glDrawArrays(GL_TRIANGLE_STRIP,0,(GLsizei)4);  	SwapBuffers(hdc);}void InitRenderer(){	int pixel_format;	memset(&pfd, 0, sizeof(PIXELFORMATDESCRIPTOR));	pfd.nSize = sizeof(PIXELFORMATDESCRIPTOR);		pfd.nVersion = 1;	pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;	pfd.iPixelType = PFD_TYPE_RGBA;	pfd.cColorBits = 24;	pfd.cDepthBits = 16;	pfd.iLayerType = PFD_MAIN_PLANE;	pixel_format = ChoosePixelFormat(hdc, &pfd);		if(!SetPixelFormat(hdc, pixel_format, &pfd)) {		OutputDebugString("unable to set pixel format\n");		return;	}	// create our render context	hglrc = wglCreateContext(hdc);	if(hglrc == NULL) {		OutputDebugString("unable to create context\n");		return;	}	if(!wglMakeCurrent(hdc, hglrc)) {		OutputDebugString("unable to make current\n");		return;	}	// set the camera	RECT rect;	GetClientRect(hwnd, &rect);	glViewport(0, 0, rect.right, rect.bottom);	glMatrixMode(GL_PROJECTION);	glLoadIdentity();	glOrtho(0.0f, rect.right - 1.0, 0.0, rect.bottom - 1.0, -1.0, 1.0);	glMatrixMode(GL_MODELVIEW);	glClearColor(1.0, 1.0, 1.0, 0.0);	glEnable(GL_POLYGON_SMOOTH);	glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);	glShadeModel(GL_SMOOTH);	glDisable(GL_DEPTH_TEST);	glEnable(GL_BLEND);	glBlendFunc(GL_SRC_ALPHA,  GL_ONE_MINUS_SRC_ALPHA);}void InitScene(){	pvert = new VertexArray[4];	ptex = new TextureArray[4];	GLfloat x1=300.0, y1=300.0, x2=128.0, y2=128.0;	pvert[0].x = x1;	pvert[0].y = y2+y1;	pvert[0].z = 0.0;	pvert[1].x = x1;	pvert[1].y = y1;	pvert[1].z = 0.0;	pvert[2].x = x1+x2;	pvert[2].y = y1+y2;	pvert[2].z = 0.0;	pvert[3].x = x1+x2;	pvert[3].y = y1;	pvert[3].z = 0.0;	//create the texture	cPNGImage* png = new cPNGImage();	png->Load("test_texture.png");	glEnable(GL_TEXTURE_2D);	glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);	unsigned int id;	glGenTextures(1, &id);	glBindTexture(GL_TEXTURE_2D, id);	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_REPEAT);	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);	unsigned char* pixmap = png->GetPixmap();	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, png->GetWidth(), png->GetHeight(), 0, GL_RGBA, 		GL_UNSIGNED_BYTE, (void*)pixmap);	GLenum e = glGetError();	ptex[0].u = 0.0;	ptex[0].v = 0.0;		ptex[1].u = 0.0;	ptex[1].v = 1.0;		ptex[2].u = 1.0;	ptex[2].v = 0.0;		ptex[3].u = 1.0;	ptex[3].v = 1.0;	glEnableClientState( GL_VERTEX_ARRAY);	glVertexPointer( 3, GL_FLOAT, 0, pvert );	glEnableClientState( GL_TEXTURE_COORD_ARRAY );	glTexCoordPointer( 2, GL_FLOAT, 0, ptex );}

Ok here is a screen shot of the output polygon:

try it without polygon smooth
Removing polygon smoothing worked - no more white line! But i dont understand why? Could anyone shed some light on this?
Good catch. Been so long since I looked at polygon_smooth I missed it.

When you are using polygon antialiasing you have to do a few other things to get it to work right. From the Redbook:


To antialias polygons in RGBA mode, you use the alpha value to represent coverage values of polygon edges. You need to enable polygon antialiasing by passing GL_POLYGON_SMOOTH to glEnable(). This causes pixels on the edges of the polygon to be assigned fractional alpha values based on their coverage, as though they were lines being antialiased. Also, if you desire, you can supply a value for GL_POLYGON_SMOOTH_HINT.


This caused the pixels along they polygon edge to become partly transparent and let you see the white background through them. If you want polygon antialiasing check out chapter 6 in the redbook and follow all the instructions there. You can't use GL_POLYGON_SMOOTH with aplha blended translucent objects because it modifies the alpha values and also requires the objects to be drawn front to back. With tranlucent object you want to sort back to front.

I think I remember reading somewhere that certain ATI cards no longer support GL_POLYGON_SMOOTH, which could explain why it only happened on your Nvidia card.

This topic is closed to new replies.

Advertisement