Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to access OpenGL rendering context on Android with Delphi XE5?

How to create OpenGL rendering context on Android device when developing an application with Delphi XE5?

Basically I don't know where to start. There are no OpenGL examples yet.

What I would expect to exist:

  • Some kind of event (Panel.OnRender) that would provide an existing context in which I could call OpenGL calls.

  • Generic TOpenGLSurface control that could be placed in forms designer

  • A way to create context on main form in runtime.

From my research so far I that TWindowManager.Render has access to OpenGL calls and uses them to render popup windows.

EDIT: Adding a Timer to a form and calling this procedure fills the screen with green, so that means GL context is already there:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  glClearColor(0, 1, 0, 0);
  glClear(GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT or GL_COLOR_BUFFER_BIT);
  eglSwapBuffers(TCustomAndroidContext.SharedDisplay, TCustomAndroidContext.SharedSurface);
end;

The question is - how to properly handle it, cos rendering on Timer in controlled environment is definitely a bad idea.

like image 647
Kromster Avatar asked Sep 17 '13 17:09

Kromster


1 Answers

I'm going to append to this answer as new details reveal.

Attempt 1

Adding a Timer to a form and calling this procedure fills the screen with green, so that means GL context is already there:

procedure TForm1.Timer1Timer(Sender: TObject);
begin
  glClearColor(0, 1, 0, 0);
  glClear(GL_DEPTH_BUFFER_BIT or GL_STENCIL_BUFFER_BIT or GL_COLOR_BUFFER_BIT);
  eglSwapBuffers(TCustomAndroidContext.SharedDisplay, TCustomAndroidContext.SharedSurface);
end;

Of course rendering on Timer in controlled environment is definitely a bad idea. The app kept on flickering on minimize/maximize.


Attempt 2

I have overridden TContextAndroid class (made a copy of Delphi unit and placed it into my app folder). I was able to inject custom code into DoEndScene method and it has successfully executed it - for this test just a simple glClear(GL_COLOR_BUFFER_BIT);. This has filled the entire application area with color. This time the application did not flickered and behaved just like normal.


Attempt 3

Here's the code that made it to work and that does not looks hacky:

types
  TMyForm = class(TForm3D)
    procedure Form3DRender(Sender: TObject; Context: TContext3D);
  end;

implementation

//Event handler for TForm.OnRender
procedure TMyForm.Form3DRender(Sender: TObject; Context: TContext3D);
begin
  glClearColor(1, 1, 0, 1);
  glClear(GL_COLOR_BUFFER_BIT);
end;
like image 138
Kromster Avatar answered Oct 18 '22 14:10

Kromster