unit typeRendrer; interface uses Windows, SDL, typeCamera; type IRenderItem = interface ['{A70C3048-1D00-4543-98EA-5F067E4EF505}'] procedure Render; end; TRendrer = class(TObject) private FRenderContext: THandle; FDeviceContext: THandle; FWindowHandle: THandle; FViewPortAspect: double; FCamera: TCamera; protected procedure RenderItem(const AItemToRender: DObject); procedure RenderFloor; public constructor Create(AHandle: THandle); destructor Destroy; override; procedure Render(ItemsToRender: DArray); procedure HandleResize(NewSize: TRect); property Camera: TCamera read FCamera; end; implementation uses dglOpenGL, SysUtils, typeVector; const NearClipping = 1; FarClipping = 1000; { TRendrer } constructor TRendrer.Create(AHandle: THandle); begin FWindowHandle := AHandle; FDeviceContext := GetDC(AHandle); FRenderContext := CreateRenderingContext(FDeviceContext, [opDoubleBuffered], 32, 24, 0, 0, 0, 0); ActivateRenderingContext(FDeviceContext, FRenderContext); FCamera := TCamera.Create; FCamera.Position := T3DVector.Create(0, 5, 15); glClearColor(0.3, 0.4, 0.7, 0.0); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); end; destructor TRendrer.Destroy; begin FCamera.Free; DeactivateRenderingContext; wglDeleteContext(FRenderContext); ReleaseDC(FWindowHandle, FDeviceContext); inherited; end; procedure TRendrer.HandleResize(NewSize: TRect); begin glViewport(newSize.Left, NewSize.Top, NewSize.Right, NewSize.Bottom); glMatrixMode(GL_PROJECTION); glLoadIdentity; if (NewSize.Bottom - NewSize.Top) = 0 then FViewPortAspect := (NewSize.Right - NewSize.Left) / 1 else FViewPortAspect := (NewSize.Right - NewSize.Left) / (NewSize.Bottom - NewSize.Top); gluPerspective(45.0, FViewPortAspect, NearClipping, FarClipping); glMatrixMode(GL_MODELVIEW); glLoadIdentity; Render(nil); end; procedure TRendrer.Render(ItemsToRender: DArray); begin glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT); glMatrixMode(GL_PROJECTION); glLoadIdentity; gluPerspective(45.0, FViewPortAspect, NearClipping, FarClipping); glMatrixMode(GL_MODELVIEW); glLoadIdentity; FCamera.ApplyTransformation; //glTranslatef(0, 0, -15); renderFloor; if assigned(ItemsToRender) then forEach(ItemsToRender, RenderItem); SwapBuffers(FDeviceContext); end; procedure TRendrer.RenderFloor; begin glPushMatrix; glBegin(GL_TRIANGLES); glColor4f(0.5, 0.5, 0.5, 1); glVertex3f(-5, 0, -5); glVertex3f(-5, 0, 5); glVertex3f( 5, 0, 5); glVertex3f( 5, 0, 5); glVertex3f( 5, 0, -5); glVertex3f(-5, 0, -5); glEnd; glPopMatrix; end; procedure TRendrer.RenderItem(const AItemToRender: DObject); var itemToRender: TObject; renderItem: IRenderItem; begin itemToRender := asObject(AItemToRender); if supports(itemToRender, IRenderItem, renderItem) then renderItem.Render; end; end.