Recent

Author Topic: Static text on OpenGLContext  (Read 19082 times)

ehj666

  • Jr. Member
  • **
  • Posts: 50
Static text on OpenGLContext
« on: February 14, 2017, 04:48:58 pm »
I am porting a bunch of raw opengl code and trying to integrate it with OpenGLContext. With direct OpenGL calls in Delphi (Windows) and directly managing device contexts, I was able to just drop TLables for example on the same canvas. When I do that with OpenGLContext they hardly display at design time and not at all at run time.

What is the prescribed method for putting static text into the OpenGLContext? This text would for instance display X, Y mouse positions as the objects rendered through opengl are manipulated, thus should not be affected by pan, zoom, rotate, etc.

Thanks

Handoko

  • Hero Member
  • *****
  • Posts: 5154
  • My goal: build my own game engine using Lazarus
Re: Static text on OpenGLContext
« Reply #1 on: February 14, 2017, 05:11:11 pm »
I'm not an expert in OpenGL, I may be wrong.

OpenGL (OpenGLContext) doesn't has feature to display text. You have to use extra library to do it or you can do as what I do. I display text on OpenGL by displaying bitmap (font texture), which I have prepared before.

This my code, which works but actually I don't remember how it works  :-[
Code: Pascal  [Select][+][-]
  1.   // GL preparation
  2.   glLoadIdentity;
  3.   glTranslatef(FXreal + Xtext, FYreal, 0);
  4.   glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
  5.   glEnable(GL_TEXTURE_2D);
  6.   glEnable(GL_BLEND);
  7.   glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  8.   glTexImage2D(GL_TEXTURE_2D, 0, 4, FTextureWidth, FTextureHeight, 0, GL_RGBA,
  9.     GL_UNSIGNED_BYTE, Pointer(FTextureBuffer));
  10.  
  11.   // Draw the text
  12.   glBegin(GL_QUADS);
  13.   glColor3ub(255, 255, 255);
  14.   glTexCoord2f(0, 0);
  15.   glVertex3f(0, 0, 0);
  16.   glTexCoord2f(1, 0);
  17.   glVertex3f(Wtext, 0, 0);
  18.   glTexCoord2f(1, 1);
  19.   glVertex3f(Wtext, FHreal, 0);
  20.   glTexCoord2f(0, 1);
  21.   glVertex3f(0, FHreal, 0);
  22.   glEnd();
« Last Edit: February 14, 2017, 05:14:51 pm by Handoko »

ehj666

  • Jr. Member
  • **
  • Posts: 50
Re: Static text on OpenGLContext
« Reply #2 on: February 14, 2017, 07:12:42 pm »
If I understand what you are saying, I do not think that is going to work. The text needs to update as the mouse moves for example, just like in the Lazarus environment where it tracks X and Y positions in the designer.

I could put another panel next to the OpenGLContext and make it look like they blend together, but I lose a bit of real estate that I do not want to give up if it can be avoided.

Handoko

  • Hero Member
  • *****
  • Posts: 5154
  • My goal: build my own game engine using Lazarus
Re: Static text on OpenGLContext
« Reply #3 on: February 14, 2017, 07:50:13 pm »
The code I gave you is just the part for displaying the texture. The whole code I wrote was a complete class of OpenGL visual controls that I want to use in my game engine. It's still not fully finished but already tested and works correctly on both Linux and Windows.

My visual gl text component works like this:
On the constructor, it writes the string using TBitmap.TextOut to memory buffer. On the paint method, I use that code I gave you to call opengl functions to display the buffer (texture).

It is easy to find tutorials to show text using OpenGL, but unfortunately most of the codes are in C and C++. I managed to make it worked by trial and error.

I could put another panel next to the OpenGLContext and make it look like they blend together, but I lose a bit of real estate that I do not want to give up if it can be avoided.
Do you mean to overlap opengl layer with other visual component on the screen? It may work but sounds not easy and I don't think it is a good idea.

I have a bookmark that someone did opengl component. It has code to show text/font using opengl, which you can learn from his code. Here is the link:
http://forum.lazarus.freepascal.org/index.php/topic,29351.0.html
« Last Edit: February 14, 2017, 07:52:21 pm by Handoko »

Handoko

  • Hero Member
  • *****
  • Posts: 5154
  • My goal: build my own game engine using Lazarus
Re: Static text on OpenGLContext
« Reply #4 on: February 14, 2017, 07:59:40 pm »
... should not be affected by pan, zoom, rotate, etc.

It shouldn't be hard. You first write the text before calling any translation, scaling and rotation.

My testing on my gl visual controls, now already able to show static text with some other gl objects that are moving and scaling, but I haven't tested with rotation.

Can you show me the code you now already have?
« Last Edit: February 14, 2017, 08:05:38 pm by Handoko »

ehj666

  • Jr. Member
  • **
  • Posts: 50
Re: Static text on OpenGLContext
« Reply #5 on: February 15, 2017, 01:52:26 am »
This picture shows what it looks like in the Delphi Windows application. The text at the top was just TLabels dropped on the canvas. The remainder is rendered through OpenGL. There is no OpenGL code to render the static text.

Akira1364

  • Hero Member
  • *****
  • Posts: 561
Re: Static text on OpenGLContext
« Reply #6 on: February 15, 2017, 03:34:08 am »
What is the canvas in your screenshot a part of? Just a form? The difference is TOpenGLControl is a standalone "TWinControl" descendant, with its own specific overridden paint procedure written with OpenGL in mind. It's not meant to have "normal" controls placed inside of it.

lainz

  • Hero Member
  • *****
  • Posts: 4468
    • https://lainz.github.io/
Re: Static text on OpenGLContext
« Reply #7 on: February 15, 2017, 04:09:41 am »
At least with the LCL. I don't know in delphi, but if you say in delphi works it can be.

I've developed some OpenGL controls, well hybrid controls (GL and LCL depending where you put them).

BGRAControlsFX:
https://github.com/bgrabitmap/bgracontrolsfx

Is not exactly text but there are buttons with text inside, so you can get the idea on how to make something similar.

ehj666

  • Jr. Member
  • **
  • Posts: 50
Re: Static text on OpenGLContext
« Reply #8 on: February 15, 2017, 04:42:02 am »
What is the canvas in your screenshot a part of? Just a form? The difference is TOpenGLControl is a standalone "TWinControl" descendant, with its own specific overridden paint procedure written with OpenGL in mind. It's not meant to have "normal" controls placed inside of it.

The canvas belongs to a TPanel. Here is part of the original code. First the initialization.
Code: Pascal  [Select][+][-]
  1.   ScreenAspectRatio :=  GetSystemMetrics(SM_CXSCREEN) /
  2.     GetSystemMetrics(SM_CYSCREEN);
  3.   Application.OnException := ExceptionGL;
  4.   pDC := GetDC(LivePlotPanel.Handle);
  5.   CgDC := TCGDeviceContext.Create(pDC);
  6.   CgDC.InitGL;
  7.   glEnable(GL_DEPTH_TEST);
  8.  

Then sizing the image to the frame.
Code: Pascal  [Select][+][-]
  1. procedure TMainAppForm.SizeImage;
  2.  
  3.   var
  4.     Range, AspectRatio: Extended;
  5.  
  6.   begin
  7.     if Assigned(Pgm) then
  8.       begin
  9.       CgDC.MakeCurrent;
  10.       glViewPort(0, 0, LivePlotPanel.Width, LivePlotPanel.Height);
  11.       glMatrixMode(GL_PROJECTION);
  12.       glLoadIdentity;
  13.       AspectRatio := LivePlotPanel.Width / LivePlotPanel.Height;
  14.       if LivePlotPanel.Width < LivePlotPanel.Height then
  15.         begin
  16.         Range := Pgm.XMax;
  17.         glOrtho(-Range, Range, -Range / AspectRatio, Range / AspectRatio, -999999.0, 999999.0);
  18.         end
  19.       else
  20.         begin
  21.         Range := Pgm.YMax;
  22.         glOrtho(-Range * AspectRatio, Range * AspectRatio, -Range, Range, -999999.0, 999999.0);
  23.         end;
  24.       glMatrixMode(GL_MODELVIEW);
  25.       glLoadIdentity;
  26.       LivePlotPanel.Invalidate;
  27.       end;
  28.   end;
  29.  

The render then begins with:
Code: Pascal  [Select][+][-]
  1.     CgDC.MakeCurrent;
  2.     glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  3.     glPushMatrix;
  4.  

And ends with:
Code: Pascal  [Select][+][-]
  1.     glMatrixMode(GL_MODELVIEW);
  2.     glLoadIdentity;
  3.     glEnd;
  4.     glFlush;
  5.     glPopMatrix;
  6.     CgDC.PageFlip;
  7.  

Of course if the OpenGLContext is not implemented like a TPanel then none of this really matters.

Handoko

  • Hero Member
  • *****
  • Posts: 5154
  • My goal: build my own game engine using Lazarus
Re: Static text on OpenGLContext
« Reply #9 on: February 15, 2017, 04:51:15 am »
Do you able to render text using OpenGL?

On your rendering routine, draw the text first before perform any tranformation, scaling and rotation.

ehj666

  • Jr. Member
  • **
  • Posts: 50
Re: Static text on OpenGLContext
« Reply #10 on: February 15, 2017, 06:21:56 am »
I don't do any of the text drawing in opengl, at least not in the original program.

I think I got it. I dropped a panel on the openglcontext, set the background colors to match, got rid of bevels, and then dropped labels on the panel.

ehj666

  • Jr. Member
  • **
  • Posts: 50
Re: Static text on OpenGLContext
« Reply #11 on: February 15, 2017, 03:09:53 pm »
Not text related, but not worth starting a new thread. I am not getting anything to display on the glcontext. Here js the init and paint code basically copied from one of the examples:

Code: Pascal  [Select][+][-]
  1. constructor TBackplot.Create(AGLControl: TopenGLControl);
  2.  
  3.   begin
  4.     BackplotControl := AGLControl;
  5.     with BackPlotControl do
  6.        begin
  7.        AutoResizeViewport := True;
  8.        MultiSampling := 4;
  9.        Invalidate;
  10.        end;
  11.   end;
  12.  
  13. procedure TBackplot.Paint;
  14.  
  15.   begin
  16.      glClearColor(0.0, 0.0, 0.0, 1.0); //Set black background
  17.      glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
  18.      glLoadIdentity;
  19.      glBegin(GL_TRIANGLES);
  20.        glColor3f(1, 0, 0);
  21.        glVertex3f( 0.0, 1.0, 0.0);
  22.        glColor3f(0, 1, 0);
  23.        glVertex3f(-1.0,-1.0, 0.0);
  24.        glColor3f(0, 0, 1);
  25.        glVertex3f( 1.0,-1.0, 0.0);
  26.      glEnd;
  27.      BackplotControl.SwapBuffers;
  28.   end;
  29.  

It is clearly getting to glClearColor because the background is turning black (and I set a break point to prove it), but the triangle does not display. I am assuming that setting AutoSizeViewport puts whatever is rendered in the frame and scales appropriately.

What am I missing?

Handoko

  • Hero Member
  • *****
  • Posts: 5154
  • My goal: build my own game engine using Lazarus
Re: Static text on OpenGLContext
« Reply #12 on: February 15, 2017, 03:18:41 pm »
The code works on my test. How did you use the code? Try this:

Code: [Select]
     glClearColor(0.0, 0.0, 0.0, 1.0); //Set black background
     glClear(GL_COLOR_BUFFER_BIT or GL_DEPTH_BUFFER_BIT);
     glLoadIdentity;
     glBegin(GL_TRIANGLES);
       glColor3f(1, 0, 0);
       glVertex3f( 0.0, 1.0, 0.0);
       glColor3f(0, 1, 0);
       glVertex3f(-1.0,-1.0, 0.0);
       glColor3f(0, 0, 1);
       glVertex3f( 1.0,-1.0, 0.0);
     glEnd;
     BackplotControl.SwapBuffers;

1. Start a new project: Lazarus main menu > File > New > Application.
2. Add GL in the uses clause.
3. Drop a TOpenGLControl to the form and resize it properly.
4. On the Object Inspector of OpenGLControl1, double click OnPaint event.
5. Drop the code there, but
6. Rename BackplotControl > OpenGLControl1.

Note:
I'm not sure what the code in the constructor for, so I simply ignore it.

And this is the result:
« Last Edit: February 15, 2017, 03:25:18 pm by Handoko »

ehj666

  • Jr. Member
  • **
  • Posts: 50
Re: Static text on OpenGLContext
« Reply #13 on: February 15, 2017, 03:39:14 pm »
Yep, that worked. So I went back to my project and removed the following from the constructor, and it worked too. That code was in the example I copied, so not sure what it is doing to prevent the triangle from displaying.

Code: Pascal  [Select][+][-]
  1.        AutoResizeViewport := True;
  2.        MultiSampling := 4;
  3.        Invalidate;
  4.  

Handoko

  • Hero Member
  • *****
  • Posts: 5154
  • My goal: build my own game engine using Lazarus
Re: Static text on OpenGLContext
« Reply #14 on: February 15, 2017, 05:12:26 pm »
Hi, I've made the code with text and random moving/scaling rectangle. All using OpenGL. You can download the Test.zip to see the code.

 

TinyPortal © 2005-2018