Delphi+OpenGL not working GL_MULTISAMPLE_ARB

Hi, i create simple application using ARB_multisample but Antialiased not woking.

main.pas
ARB_multisample.pas
DGLUT.pas

Help pliase!
not using


 glHint(GL_POLYGON_SMOOTH_HINT, GL_NICEST);
 glEnable(GL_POLYGON_SMOOTH);
 glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
 glEnable(GL_POINT_SMOOTH);
 glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
 glEnable(GL_LINE_SMOOTH);

procedure TmainGL.FormCreate(Sender: TObject);
begin
 DC := GetDC (Handle);
 SetDCPixelFormat(DC, false);
 hrc := wglCreateContext(DC);
 wglMakeCurrent(DC, hrc);

 DC := GetDC (Handle);
 SetDCPixelFormat(DC, true);
 hrc := wglCreateContext(DC);
 wglMakeCurrent(DC, hrc);

 Init;
end;

You are calling SetPixelFormat twice for the same window, which is not allowed.
You will need two separate forms, the first window (Form1) will be a splash screen or menu, while the second form (MainGL) will be the OpenGL display window.
Use SetDCPixelFormat(DC, false) on the first window.
Although OpenGL will not be used to draw to this window, you still need an OpenGL context for it.
Use this context to call InitMultisample and obtain a multisample PixelFormat number, but use this to SetPixelFormat on the SECOND window DC.
Then wglMakeCurrent(0, 0) and delete the context of the first window.
Create and make current a context on the second window, and call Init, before you show it.

Thank you! this is hard for me, please upload the sample or code.

this program correctly working for video card not supported AA or minimum supported AA?


var
  DC : HDC;
  hrc: HGLRC;
  AAFormat: Integer;

....................................
....................................
//*********************************************
procedure SetDCPixelFormat (hdc : HDC);
var
  nPixelFormat: Integer;
  pfd: TPixelFormatDescriptor;
begin
  FillChar(pfd, SizeOf(pfd), 0);

  With pfd do begin
	dwFlags   := PFD_DRAW_TO_WINDOW or
				 PFD_SUPPORT_OPENGL or
				 PFD_DOUBLEBUFFER;
	cDepthBits:= 32;
  end;

  if (AAFormat > 0) then nPixelFormat := AAFormat
  else nPixelFormat := ChoosePixelFormat(DC, @pfd);

  SetPixelFormat(DC, nPixelFormat, @pfd);
end;

//*********************************************
procedure TopenglFrm.GetPixelFormat;
const
  WGL_SAMPLE_BUFFERS_ARB = $2041;
  WGL_SAMPLES_ARB		   = $2042;
  WGL_DRAW_TO_WINDOW_ARB = $2001;
  WGL_SUPPORT_OPENGL_ARB = $2010;
  WGL_DOUBLE_BUFFER_ARB  = $2011;
  WGL_COLOR_BITS_ARB	 = $2014;
  WGL_DEPTH_BITS_ARB	 = $2022;
  WGL_STENCIL_BITS_ARB   = $2023;
  AASamples : Integer	= 16;
var
  wglChoosePixelFormatARB:
  function  (hdc: HDC;
			 const piAttribIList: PGLint;
			 const pfAttribFList: PGLfloat;
			 nMaxFormats: GLuint;
			 piFormats: PGLint;
			 nNumFormats: PGLuint): BOOL; stdcall;

  fAttributes: array [0..1] of Single;
  iAttributes: array [0..17] of Integer;
  pfd		: PIXELFORMATDESCRIPTOR;
  iFormat	: Integer;
  hwnd	   : Cardinal;
  wnd		: TWndClassEx;
  numFormats : Cardinal;
  Format	 : Integer;
begin
  ZeroMemory(@wnd, SizeOf(wnd));
  with wnd do
  begin
	cbSize		:= SizeOf(wnd);
	lpfnWndProc   := @DefWindowProc;
	hCursor	   := LoadCursor(0, IDC_ARROW);
	lpszClassName := 'GetPixelFormat';
  end;
  RegisterClassEx(wnd);
  hwnd := CreateWindow('GetPixelFormat', nil, WS_POPUP, 0, 0, 0, 0, 0, 0, HInstance, nil);
  DC := GetDC(hwnd);
  FillChar(pfd, SizeOf(pfd), 0);
  with pfd do
  begin
	nSize		:= SizeOf(TPIXELFORMATDESCRIPTOR);
	nVersion	 := 1;
	dwFlags	  := PFD_DRAW_TO_WINDOW or
					PFD_SUPPORT_OPENGL or
					PFD_DOUBLEBUFFER;
	iPixelType   := PFD_TYPE_RGBA;
	cColorBits   := 32;
	cDepthBits   := 24;
	cStencilBits := 8;
	iLayerType   := PFD_MAIN_PLANE;
  end;
  SetPixelFormat(DC, ChoosePixelFormat(DC, @pfd), @pfd);
  wglMakeCurrent(DC, wglCreateContext(DC));
  fAttributes[0]  := 0;
  fAttributes[1]  := 0;
  iAttributes[0]  := WGL_DRAW_TO_WINDOW_ARB;
  iAttributes[1]  := 1;
  iAttributes[2]  := WGL_SUPPORT_OPENGL_ARB;
  iAttributes[3]  := 1;
  iAttributes[4]  := WGL_SAMPLE_BUFFERS_ARB;
  iAttributes[5]  := 1;
  iAttributes[6]  := WGL_SAMPLES_ARB;
  //iAttributes[7]:= calc;
  iAttributes[8]  := WGL_DOUBLE_BUFFER_ARB;
  iAttributes[9]  := 1;
  iAttributes[10] := WGL_COLOR_BITS_ARB;
  iAttributes[11] := 32;
  iAttributes[12] := WGL_DEPTH_BITS_ARB;
  iAttributes[13] := 24;
  iAttributes[14] := WGL_STENCIL_BITS_ARB;
  iAttributes[15] := 8;
  iAttributes[16] := 0;
  iAttributes[17] := 0;
  wglChoosePixelFormatARB := wglGetProcAddress('wglChoosePixelFormatARB');
  iAttributes[7] := AASamples;
  if wglChoosePixelFormatARB(GetDC(hWnd), @iattributes, @fattributes, 1, @Format, @numFormats) and (numFormats >= 1) then
  begin
	AAFormat := Format;
  end;
  ReleaseDC(hwnd, DC);
  DestroyWindow(hwnd);
  wglMakeCurrent(0, 0);
  wglDeleteContext(DC);
end;

//*********************************************
procedure TopenglFrm.FormCreate(Sender: TObject);
begin
 GetPixelFormat;
 DC := GetDC (Handle);
 SetDCPixelFormat(DC);
 hrc := wglCreateContext(DC);
 wglMakeCurrent(DC, hrc);
end;

//*********************************************
procedure TopenglFrm.FormDestroy(Sender: TObject);
begin
 wglMakeCurrent(0, 0);
 wglDeleteContext(hrc);
 ReleaseDC (Handle, DC);
 DeleteDC (DC);
end;

Here’s some more detail of using a second form to access wglChoosePixelFormatARB.
This is based on your original code, in your last post you use windows functions to create a new window, but its much simpler to just let delphi create it for you.

From the menu select File/New/Form to create a new form unit.

Select View/Units, select the program name from the list and press OK.
This displays the program DPR file which should have two lines like this:
Application.CreateForm(TForm2, Form2);
Application.CreateForm(TmainGL, mainGL);

They will probably be in the wrong order, so swap the two lines so that the new form is created before your mainGL form.
Both Forms should have visible=true in the object inspector.

Duplicate the mainGL variables in TForm2:

  TForm2 = class(TForm)
  private
  public
   DC : HDC;
   hrc: HGLRC;
  end;

Add to Unit2:
implementation
uses main;

The FormCreate methods of TmainGL and TForm2 should be as follows:

procedure TForm2.FormCreate(Sender: TObject);
var
 pfd: TPixelFormatDescriptor;
begin
 //Setup a temporary context so we can call wglChoosePixelFormatARB
 FillChar(pfd, SizeOf(pfd), 0);
 DC := GetDC (Handle);
 SetPixelFormat( DC, 1, @PFD ); {Dont care what pixelformat is, as long as its hardware accelerated}
 hrc := wglCreateContext(DC);
 wglMakeCurrent(DC, hrc);
end;

procedure TmainGL.FormCreate(Sender: TObject);
var
 pfd: TPixelFormatDescriptor;
begin
 //
 DC := GetDC (Handle);
 SetDCPixelFormat(DC, true);
 hrc := wglCreateContext(DC);
 wglMakeCurrent(DC, hrc);

 //Setup the OpenGL context 
 Init;
end;

To prevent flicker you should also override the EraseBackground message handler, and if you want to change any of the window class parameters you can also override CreateParams:

  TmainGL = class(TForm)
    procedure CreateParams(var Params: TCreateParams); override;
  private
    { Private declarations }
    procedure ERASEBKGND(var Message: TWMEraseBkGnd); message WM_ERASEBKGND;
  end;

procedure TmainGL.ERASEBKGND(var Message: TWMEraseBkGnd);
begin
  Message.Result := 1 {This prevents flicker from windows floodfilling client area}
end;

procedure TmainGL.CreateParams(var Params: TCreateParams);
begin
  inherited; {This sets-up most of class, we just add OwnDC and any other flags we want to the class}
  Params.WindowClass.style := CS_HReDraw + CS_VReDraw + CS_OwnDC + CS_DBLCLKS;
  Params.Style := Params.Style or WS_CLIPCHILDREN;
end;

Thanks!

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.