Welcome to the new Friends-of-FPC!

Here you can find all kinds of information about the FreePascal Compiler. We have many tutorials and howtos as well as a selection of tools to help you with your programming. We also have some example codes for you. And if you want to contribute some information/ sources/ tools yourself you can do so.
Also we have finally relaunched the FoFPC forum. It's your chance for some Q&A about everything FreePascal.

Friends-of-FPC

Tutorials: Learn how to code with FreePascal.

Source Codes: A collection of examples, miscellaneous source codes and open source stuff.

Tools and Help Files: Intro- duction of some tools that might help you with FPC.

Community

Forum: Ask or answer questions about the FreePascal Compiler, programming or just babble about coding.

Contribute! Contribute your own Tutorial, Source Codes or Tools and send them to us!

Website

About: Information about Friends-of-FPC.org.

OpenGL/ FPC - Chapter 2 - by Delax

First of all, an OpenGL window is just like any another window. It has a Window Class, a Device Context etc. If you don't know what all this is - don't worry - you don't really need to know it to play around with OpenGL. If you want to go deeper into OpenGL, take a tutorial about Windows and look it up.

So for a start, let's just define and create a Window.

function WindowRegister: Boolean;
var
  WindowClass: WndClass;
begin
  WindowClass.Style := cs_hRedraw or cs_vRedraw;
  WindowClass.lpfnWndProc := WndProc(@GLWndProc);
  WindowClass.cbClsExtra := 0;
  WindowClass.cbWndExtra := 0;
  WindowClass.hInstance := system.MainInstance;
  WindowClass.hIcon := LoadIcon(0, idi_Application);
  WindowClass.hCursor := LoadCursor(0, idc_Arrow);
  WindowClass.hbrBackground := GetStockObject(WHITE_BRUSH);
  WindowClass.lpszMenuName := nil;
  WindowClass.lpszClassName := 'GLWindow';

  WindowRegister := RegisterClass(WindowClass) <> 0;
end;

There is our Window Class. The only thing special is that we don't define a background. We want to draw OpenGL stuff in our window, so we don't need one and set hbrBackground to plain white. Also note that the function returns true or false, depending on the success of registering the Window Class.

Now we create the window. Nothing special either.

function WindowCreate(pcApplicationName : pChar): HWnd;
var
  hWindow: HWnd;		// Handle to Window
  dmScreenSettings : DEVMODE;	// Used for Full Screen Mode
begin

  hWindow := CreateWindow('GLWindow',
			  pcApplicationName,
			  WS_CAPTION OR WS_POPUPWINDOW OR WS_VISIBLE 
			  OR WS_CLIPSIBLINGS OR WS_CLIPCHILDREN,
			  cw_UseDefault,
			  cw_UseDefault,
			  width,
			  height,
			  0, 0,
			  system.MainInstance,
			  nil);

  if hWindow <> 0 then begin
    ShowWindow(hWindow, CmdShow);
    UpdateWindow(hWindow);
  end;

  WindowCreate := hWindow;
end;

Note that we create our window with variable width and height. As a result the function returns the Windows Handle of the window.

And now the initialization of our window. First, we get a Device Context and then we define a Pixel Format for our window.

You must set PFD_SUPPORT_OPENGL in pfd.dwFlags. That way, our window supports OpenGL. There are a couple other OpenGL related styles like PFD_DRAW_TO_WINDOW and/ or PFD_DOUBLEBUFFER. Just look at a list in your local OpenGL info center ;)

Next up is rcWindow := wglCreateContext( dcWindow );. Here we get an OpenGL Render Context for our window. Last thing we do is tell Windows that the window will be the receiver of our OpenGL calls.

function WindowInit(hParent : HWnd): Boolean;
var
  FunctionError : integer;
  pfd : PIXELFORMATDESCRIPTOR;
  iFormat : integer;	// Pixel Format

begin

 FunctionError := 0;

  dcWindow := GetDC( hParent );	// Get Device Context

  FillChar(pfd, sizeof(pfd), 0);	// Define Pixel Format
  pfd.nSize         := sizeof(pfd);
  pfd.nVersion      := 1;
  pfd.dwFlags       := PFD_SUPPORT_OPENGL OR PFD_DRAW_TO_WINDOW OR PFD_DOUBLEBUFFER;
  pfd.iPixelType    := PFD_TYPE_RGBA;
  pfd.cColorBits    := bits;
  pfd.cDepthBits    := 16;
  pfd.iLayerType    := PFD_MAIN_PLANE;

  iFormat := ChoosePixelFormat( dcWindow, @pfd );

  if (iFormat = 0) then FunctionError := 1;

  SetPixelFormat( dcWindow, iFormat, @pfd );
  rcWindow := wglCreateContext( dcWindow );

  if (rcWindow = 0) then FunctionError := 2;

  wglMakeCurrent( dcWindow, rcWindow );

 if FunctionError = 0 then WindowInit := true else WindowInit := false;

end;

And here we go. If you run these procedures one by one, you've got an OpenGL window!

The next step is to configure OpenGL itself. We'll start off by a simple one-liner.

PROCEDURE OpenGL_Init;
begin

  glClearColor( 0.0, 0.0, 0.0, 1.0 );

end;

With glClearColor() you can define the color the window will be cleared with. The values are in RGB, meaning that the first value is the intensity of red, the second of green and the third is the intensity of blue. The values range from 0.0 (min) to 1.0 (max). So 1.0, 0.0, 0.0 would be a bright red. The forth value is the alpha value, but more on that later.

And now the main loop. Here we add one line: SwapBuffers( window_hDC );. With SwapBuffers, you copy the content of the buffer to the screen, thus making it all visible. Without these line, your OpenGL code would be pretty useless.

So here is the first sample program. It initializes the window and does ... nothing ;) Get the complete source file here. Look at it, compile it, and we'll meet again in the next part.

Delax/ Sundancer Inc.
[delax@sundancerinc.de]

Back to previous page

Useful Links









Link to us