I rendered some lines to a bitmap and the same lines directly to screen and the image differs on some graphic-cards. For example on a Geforce 2 MX440 with Microsoft driver everything is fine but if i use the NVIDEA driver the lines differ. On boards with Matrox G400 everything is ok but on boards with ATI Radeon 7000 lines differ too.
Here’s a short example which can be used to reproduce the effect. It draws green circles in a bitmap and displays it on the screen. Then it draws the same circles with red color in the same window. On some PCs you can still see some green points beside the red circles.
Does anybody know how to avoid the green pixels an all graphicboards?
#include <windows.h>
#include <gl/gl.h>
#include <math.h>
HBITMAP hbitmap;
HDC memdc;
HGLRC hglrc;
LRESULT WINAPI MainWndProc(HWND, UINT, WPARAM, LPARAM);
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
LPSTR lpszCmdLine, int nCmdShow)
{
WNDCLASS wc;
MSG msg;
HWND hWnd;
if(!hPrevInstance)
{
wc.lpszClassName=“OpenGLAppClass”;
wc.lpfnWndProc=MainWndProc;
wc.style=CS_OWNDC | CS_VREDRAW | CS_HREDRAW;
wc.hInstance=hInstance;
wc.hIcon=LoadIcon(NULL, IDI_APPLICATION);
wc.hCursor=LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground=(HBRUSH)(COLOR_WINDOW+1);
wc.lpszMenuName=NULL;
wc.cbClsExtra=0;
wc.cbWndExtra=0;
RegisterClass(&wc);
}
hWnd=CreateWindow(“OpenGLAppClass”,
“OpenGL Application”,
WS_OVERLAPPEDWINDOW|WS_CLIPCHILDREN|WS_CLIPSIBLINGS,
0,0,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,hInstance,NULL);
ShowWindow(hWnd, nCmdShow);
while(GetMessage(&msg,NULL,0,0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
void InitGL(HWND hwnd)
{
RECT rect;
GetClientRect(hwnd,&rect);
glViewport(0,0,rect.right,rect.bottom);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glOrtho((GLdouble) -0.5,(GLdouble) (rect.right-0.5),
(GLdouble) -0.5,(GLdouble) (rect.bottom-0.5),
(GLdouble) -1.,(GLdouble) 1.);
glDrawBuffer(GL_FRONT);
glShadeModel(GL_FLAT);
glEnable(GL_LINE_STIPPLE);
glLineStipple(1,-1);
glLineWidth(1);
glFlush();
}
#define PI 3.1415926535897932384626433832795
void DrawGL(HWND hwnd)
{
RECT rect;
int i,ianzs,ix,iy;
double hr,hxm,hym;
double xh,yh,hxp,hyp;
double sinal,cosal;
double hxa,hya;
double alpha;
GetClientRect(hwnd,&rect);
hxm=((rect.right+rect.left)0.5);
hym=((rect.top+rect.bottom)0.5);
for(hr=hxm/2;hr>10.;hr-=5.)
{
alpha=acos(1.0-0.4/hr);
if(alpha<0.00001) alpha=0.00001;
ianzs=(int)((PI+PI)/alpha);
alpha=(PI+PI)/ianzs;
sinal=sin(alpha);
cosal=cos(alpha);
hxa=hxm+hr;
hya=hym;
glBegin(GL_LINE_STRIP);
ix=(int)(hxa);
iy=(int)(hya);
glVertex2i(ix,iy);
hxp=hxa;
hyp=hya;
for(i=1;i<ianzs;i++)
{
xh=hxp-hxm;
yh=hyp-hym;
hxp=xhcosal-yhsinal+hxm;
hyp=xhsinal+yhcosal+hym;
ix=(int)(hxp);
iy=(int)(hyp);
glVertex2i(ix,iy);
}
ix=(int)(hxa);
iy=(int)(hya);
glVertex2i(ix,iy);
glEnd();
}
glFlush();
}
void InitWindow(HWND hwnd)
{
PIXELFORMATDESCRIPTOR pfd;
int iPixelFormat;
HDC hdc;
hdc=GetDC(hwnd);
pfd.nSize=sizeof(pfd);
pfd.nVersion=1;
pfd.dwFlags=PFD_DRAW_TO_WINDOW| PFD_SUPPORT_OPENGL | PFD_SUPPORT_GDI;
pfd.cAccumAlphaBits=0;
pfd.cAccumBits=0;
pfd.cAccumBlueBits=0;
pfd.cAccumGreenBits=0;
pfd.cAccumRedBits=0;
pfd.cAlphaBits=0;
pfd.cAlphaShift=0;
pfd.cAuxBuffers=0;
pfd.cBlueBits=0;
pfd.cBlueShift=0;
pfd.cColorBits=(unsigned char) 32;
pfd.cDepthBits=32;
pfd.cGreenBits=0;
pfd.cGreenShift=0;
pfd.cRedBits=0;
pfd.cRedShift=0;
pfd.cStencilBits=0;
pfd.dwDamageMask=0;
pfd.dwLayerMask=0;
pfd.dwVisibleMask=0;
pfd.iLayerType=PFD_MAIN_PLANE;
pfd.iPixelType=PFD_TYPE_RGBA;
iPixelFormat=ChoosePixelFormat(hdc, &pfd);
DescribePixelFormat(hdc,iPixelFormat,sizeof(PIXELFORMATDESCRIPTOR),&pfd);
SetPixelFormat(hdc,iPixelFormat,&pfd);
hglrc=wglCreateContext(hdc);
ReleaseDC(hwnd,hdc);
}
void CreateGLBitmap(HWND hwnd)
{
int iPixelFormat;
int ncolor;
PIXELFORMATDESCRIPTOR pfd;
BITMAPINFO *biinfo;
void *lpbits;
RECT rect;
int size;
HGLRC hglrn;
HDC hdc;
if(memdc) DeleteDC(memdc);
if(hbitmap) DeleteObject(hbitmap);
memdc=NULL;
hbitmap=NULL;
GetClientRect(hwnd,&rect);
hdc=GetDC(hwnd);
memdc=CreateCompatibleDC(hdc);
if(!memdc) return;
iPixelFormat=GetPixelFormat(hdc);
DescribePixelFormat(hdc,iPixelFormat,sizeof(PIXELFORMATDESCRIPTOR),&pfd);
if((pfd.iPixelType==PFD_TYPE_RGBA)&&(pfd.cColorBits>8))
ncolor=0;
else
ncolor=1<<pfd.cColorBits;
biinfo=(BITMAPINFO )malloc(sizeof(BITMAPINFO)+ncolorsizeof(RGBQUAD));
if(biinfo==NULL) return;
ZeroMemory(biinfo, sizeof(BITMAPINFO));
biinfo->bmiHeader.biSize=sizeof(BITMAPINFOHEADER);
biinfo->bmiHeader.biWidth=rect.right;
biinfo->bmiHeader.biHeight=rect.bottom;
biinfo->bmiHeader.biPlanes=1;
if(pfd.cColorBits<=4)
biinfo->bmiHeader.biBitCount=4;
else if(pfd.cColorBits<=8)
biinfo->bmiHeader.biBitCount=8;
else if(pfd.cColorBits<=16)
biinfo->bmiHeader.biBitCount=16;
else if(pfd.cColorBits<=24)
biinfo->bmiHeader.biBitCount=24;
else
biinfo->bmiHeader.biBitCount=32;
biinfo->bmiHeader.biCompression=BI_RGB;
size=biinfo->bmiHeader.biWidth * biinfo->bmiHeader.biBitCount;
size=((size + 31)/32 * 4);
biinfo->bmiHeader.biSizeImage=size * biinfo->bmiHeader.biHeight;
hbitmap=CreateDIBSection(hdc,biinfo,DIB_RGB_COLORS,
&lpbits,NULL,(DWORD)0);
free(biinfo);
if(!hbitmap) return;
SelectObject(memdc,hbitmap);
pfd.nSize=sizeof(pfd);
pfd.nVersion=1;
pfd.dwFlags=PFD_DRAW_TO_BITMAP| PFD_SUPPORT_OPENGL | PFD_SUPPORT_GDI;
pfd.cAccumAlphaBits=0;
pfd.cAccumBits=0;
pfd.cAccumBlueBits=0;
pfd.cAccumGreenBits=0;
pfd.cAccumRedBits=0;
pfd.cAlphaBits=0;
pfd.cAlphaShift=0;
pfd.cAuxBuffers=0;
pfd.cBlueBits=0;
pfd.cBlueShift=0;
pfd.cColorBits=(unsigned char) biinfo->bmiHeader.biBitCount;
pfd.cDepthBits=32;
pfd.cGreenBits=0;
pfd.cGreenShift=0;
pfd.cRedBits=0;
pfd.cRedShift=0;
pfd.cStencilBits=0;
pfd.dwDamageMask=0;
pfd.dwLayerMask=0;
pfd.dwVisibleMask=0;
pfd.iLayerType=PFD_MAIN_PLANE;
pfd.iPixelType=PFD_TYPE_RGBA;
iPixelFormat=ChoosePixelFormat(memdc, &pfd);
DescribePixelFormat(memdc,iPixelFormat,sizeof(PIXELFORMATDESCRIPTOR),&pfd);
SetPixelFormat(memdc,iPixelFormat,&pfd);
hglrn=wglCreateContext(memdc);
wglMakeCurrent(memdc,hglrn);
InitGL(hwnd);
glClearColor(0.,0.,1.,0.0);
glClear(GL_COLOR_BUFFER_BIT);
glColor3f((GLfloat)0.0,(GLfloat)1.0,(GLfloat)0.0);
DrawGL(hwnd);
wglDeleteContext(hglrn);
ReleaseDC(hwnd,hdc);
}
LRESULT CALLBACK MainWndProc(HWND hwnd,UINT msg,WPARAM wParam,LPARAM lParam)
{
PAINTSTRUCT ps;
HDC hdc;
switch(msg)
{
case WM_CREATE:
InitWindow(hwnd);
CreateGLBitmap(hwnd);
break;
case WM_PAINT:
hdc=BeginPaint(hwnd,&ps);
if(memdc) BitBlt(hdc,ps.rcPaint.left,ps.rcPaint.top,
ps.rcPaint.right-ps.rcPaint.left,ps.rcPaint.bottom-ps.rcPaint.top,
memdc,ps.rcPaint.left,ps.rcPaint.top,SRCCOPY);
wglMakeCurrent(hdc,hglrc);
InitGL(hwnd);
glColor3f((GLfloat)1.0,(GLfloat)0.0,(GLfloat)0.0);
DrawGL(hwnd);
wglMakeCurrent(NULL,NULL);
EndPaint(hwnd,&ps);
break;
case WM_DESTROY:
if(hglrc)
{
wglMakeCurrent(NULL,NULL);
wglDeleteContext(hglrc);
}
if(memdc) DeleteDC(memdc);
if(hbitmap) DeleteObject(hbitmap);
PostQuitMessage(0);
break;
case WM_SIZE:
CreateGLBitmap(hwnd);
default:
return(DefWindowProc(hwnd, msg, wParam, lParam));
}
return 0;
}