Overlaying graphics on top of OpenGL render context
Asked Answered
D

1

5

I am trying to overlay graphics on top of my OpenGL render scene.

I have managed to get it up and running but the drop in FPS is somewhat too much.

I am currently using GLScene in combination with Graphics32.

What I do is to render the GLScene Rendering Context to a bitmap, apply that bitmap to a TImageView32, and do some final UI touches inside the TImage32.

The code I am using to render to a bitmap is the following, which also reduces FPS is:

procedure RenderToBitmap;
  var b: TBitmap;
begin
  b:=TBitmap.Create;
  b:=GLSceneViewer.Buffer.CreateSnapShotBitmap; //TGLSceneViewer
  ImgVwr32.Bitmap.Assign(b); //TImageViewer32
  b.Free;
end;

I have tried some other code (see below), which gives me a realtime rendering, but I can not modify the "Bitmap" property of the ImageViewer32. In other words: The GLScene Rendering context is being rendered, but none of my own graphics is rendered. The code:

//The following line is put inside the FormCreate call
GLSceneViewer.Buffer.CreateRC(GetDC(ImgVwr32.Handle),false);

How can I properly overlay graphics on top of the rendering context, or copy the rendering context output, without losing FPS?

Dewar answered 6/10, 2014 at 17:51 Comment(0)
D
8

Well, by avoiding the whole GPU→CPU→GPU copy roundtrips. Upload your overlay into a OpenGL texture and draw that over the whole scene using a large textured quad.

OpenGL is not a scene graph, it's just a somewhat more sophisticated drawing API. You can change the viewport and transformation parameters at any time without altering the pixels drawn so far. So it's easy to just switch into a screen space coordinate system and draw the overlay using that.

Disunion answered 6/10, 2014 at 18:13 Comment(7)
Interesting. I have tried to map quads so that 1 unit of position is equal to 1 pixel on the screen. How exactly do you suggest to overlay my GUI? Do you have some reference articles or something?Dewar
Normally you'd choose a coordinate system so that the range [-1, 1] covers the whole viewport. Don't try to think Pixels in OpenGL, except for a few special cases it doesn't make sense, and when you think in pixels be prepared to bend your brain, because it's not trivial. Pixel centers are not at integer coordinates, but at x+0.5 in the viewport and for textures the coordinates 0 and one refer to the outer edges of the border pixels, i.e. if the texture is in wrap mode, right between the wrapping texture pixels.Disunion
Alright. I have most likelt bent my brain enough then. That's why I was thinking about overlaying 2D graphics on top of the OpenGL render context, but as I said in my question: How can I do that efficiently without losing FPS?Dewar
@AidVllasaliu: After drawing your scene set glViewport to the position and size of your overlay image, switch to a orthographic projection with parameters (0,1,0,1,-1,1) and draw a quad (0,0),(1,0),(1,1),(0,1) with texture coordinates of the same value with the texture being your overlay. Use OpenGL blending for the overlay effect.Disunion
I saw your answer to a similar question at #14909243Dewar
The code in your answer seems to be in C/C++, do you have similar code in Pascal for Delphi? I think that might be what I am looking for.Dewar
@AidVllasaliu: No it's not really what you need. It does a GPU→CPU transfer and back again. You want exactly the opposite of that code. Also it's been an awfully long time since the last time I wrote something in Delphi or Object Pascal (it's been close to 20 years, so I'm quite rusty in it; also I no longer have a compiler for it around, that compiles to a modern Windows).Disunion

© 2022 - 2024 — McMap. All rights reserved.