Silverfrost Forums

Welcome to our forums

Opengl Extensions

25 Jan 2021 9:17 #26972

This question is probably for Silverfrost Developers.

The clearwin support for Opengl has not kept pace with the more recent extensions to the Opengl API.

In particular the number of wgl function prototypes in the WINGDI.H are now very limited.

One feature that I would like to make use of, which pretty well all graphic cards support, is multi-sampling which is an anti-aliasing feature which smooths jagged lines. This requires the setting up of a multisampled frame buffer.

The Opengl documentation shows that this can be set up with the appropriate wgl function calls or more simply using the GLUT library to initialise the display.

Neither of these options seem to currently available with the Silverfrost compilers.

Is there any way that multi-sampling can be implemented at present ?

Ideally an extra argument to the %og statement would be useful

eg. %^og[stencil,double,depth32,multisample4]

26 Jan 2021 6:25 #26973

You don't have glut32.dll ?

26 Jan 2021 7:23 #26974

FLEXPLAN3D

Could you provide links to the functions that you want to use?

If they are not already in opengl.ins then it should be a simple matter to add them.

Providing support via the %gl options may be possible. Again some illustrative C code would help.

30 Jan 2021 10:30 #26990

This code to set multisampling is taken from Opengl Superbible by R wright. I cannot get it to compile with SCC compiler.

I think if this worked I could access the multi-sampling I require.

As you can see it needs quite a few extra wgl functions.

#include <windows.h> //extract from GLTools.h
int gltIsWGLExtSupported(HDC hDC, const char *szExtension);

// extract from WGLEXT.h extern BOOL WINAPI wglGetPixelFormatAttribivARB (HDC, int, int, UINT, const int *, int *); extern BOOL WINAPI wglChoosePixelFormatARB (HDC, const int *, const FLOAT *, UINT, int *, UINT *); typedef BOOL (WINAPI * PFNWGLGETPIXELFORMATATTRIBIVARBPROC) (HDC hdc, int iPixelFormat, int iLayerPlane, UINT nAttributes, const int *piAttributes, int *piValues);

// Find the best available pixelformat, including if Multisample is available void FindBestPF(HDC hDC, int *nRegularFormat, int *nMSFormat);

/////////////////////////////////////////////////////////////////////////////// // Select pixelformat with desired attributes // Returns the best available 'regular' pixel format, and the best available // Multisampled pixelformat (0 if not available) void FindBestPF(HDC hDC, int *nRegularFormat, int *nMSFormat) { *nRegularFormat = 0; *nMSFormat = 0;

// easy check, just look for the entrypoint
if(gltIsWGLExtSupported(hDC, \'WGL_ARB_pixel_format\'))
    if(wglGetPixelFormatAttribivARB == NULL)
        wglGetPixelFormatAttribivARB = (PFNWGLGETPIXELFORMATATTRIBIVARBPROC)
                             wglGetProcAddress(\'wglGetPixelFormatAttribivARB\');

// First try to use new extended wgl way
if(wglGetPixelFormatAttribivARB != NULL)
    {
    // Only care about these attributes
    int nBestMS = 0;
    int i;
    int iResults[9];
    int iAttributes [9] = {    WGL_SUPPORT_OPENGL_ARB, // 0
                               WGL_ACCELERATION_ARB,   // 1
                               WGL_DRAW_TO_WINDOW_ARB, // 2
                               WGL_DOUBLE_BUFFER_ARB,  // 3
                               WGL_PIXEL_TYPE_ARB,     // 4
                               WGL_DEPTH_BITS_ARB,     // 5
                               WGL_STENCIL_BITS_ARB,   // 6
                               WGL_SAMPLE_BUFFERS_ARB, // 7
                               WGL_SAMPLES_ARB };      // 8

    // How many pixelformats are there?
    int nFormatCount[] = { 0 };
    int attrib[] = { WGL_NUMBER_PIXEL_FORMATS_ARB };
    wglGetPixelFormatAttribivARB(hDC, 1, 0, 1, attrib, nFormatCount);

    // Loop through all the formats and look at each one
    for(i = 0; i < nFormatCount[0]; i++)
        {
        // Query pixel format
        wglGetPixelFormatAttribivARB(hDC, i+1, 0, 9, iAttributes, iResults);

        // Match? Must support OpenGL AND be Accelerated AND draw to Window 
        if(iResults[0] == 1 &amp;&amp; iResults[1] == WGL_FULL_ACCELERATION_ARB &amp;&amp; iResults[2] == 1)
        if(iResults[3] == 1)                    // Double buffered
        if(iResults[4] == WGL_TYPE_RGBA_ARB)    // Full Color
        if(iResults[5] >= 16)                   // Any Depth greater than 16
        if(iResults[6] > 0)                     // Any Stencil depth (not zero)
            {
            // We have a candidate, look for most samples if multisampled
            if(iResults[7] == 1)	            // Multisampled
                {
                if(iResults[8] > nBestMS)       // Look for most samples
                    {
                    *nMSFormat = i;			// Multisamples	
                    nBestMS = iResults[8];	// Looking for the best
                    }
                }
            else // Not multisampled
                {
                // Good enough for \'regular\'. This will fall through
                *nRegularFormat = i;
                }
            }
        }
    }
else
    {
    // Old fashioned way... 
    // or multisample
    PIXELFORMATDESCRIPTOR pfd = { 
    sizeof(PIXELFORMATDESCRIPTOR),
    1,
    PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
    PFD_TYPE_RGBA,      // Full color
    32,                 // Color depth
    0,0,0,0,0,0,0,      // Ignored
    0,0,0,0,            // Accumulation buffer
    24,                 // Depth bits
    8,                  // Stencil bits
    0,0,0,0,0,0 };      // Some used, some not

    *nRegularFormat = ChoosePixelFormat(hDC, &amp;pfd);
    }
}
30 Jan 2021 4:11 #26991

FLEXPLAN3D

Your post may have been truncated. If it is very large then you could use something like DropBox.

30 Jan 2021 7:18 #26992

Paul

My apologies - here is the missing bit.

I can send a file if you wish, but I don't have a contact e-mail for you.

Thanks

Bob

             }
            }
        }
    }
else
    {
    // Old fashioned way... 
    // or multisample
    PIXELFORMATDESCRIPTOR pfd = { 
    sizeof(PIXELFORMATDESCRIPTOR),
    1,
    PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
    PFD_TYPE_RGBA,      // Full color
    32,                 // Color depth
    0,0,0,0,0,0,0,      // Ignored
    0,0,0,0,            // Accumulation buffer
    24,                 // Depth bits
    8,                  // Stencil bits
    0,0,0,0,0,0 };      // Some used, some not

    *nRegularFormat = ChoosePixelFormat(hDC, &amp;pfd);
    }
}
30 Mar 2021 12:02 #27364

Bob

I have had a look at your code.

I can get it to compile by downloading wglext.h from the Internet and by commenting out the call to wglGetProcAddress (which would not be needed if the relevant DLL is available at link time).

Sorry but I don't see any way to progress from this point.

30 Mar 2021 3:18 #27365

Paul

Thanks for looking at it - if you can think of any other way of implemented multi-sampling I would still be interested.

Bob

29 May 2021 8:07 #27877

FLEXPLAN3D By the way, do you know how to write text on OpenGL plot like on usual 2D picture? So that when you turn the 3D picture, the text will be on the same place staying still. Same like the title on PowerPoint presentations is on top no matter what content is below

30 May 2021 3:01 #27881

The easiest way I think is to disable depth testing before drawing the text. i.e call glDisable(GL_DEPTH_TEST)

There is a Silverfrost Opengl example (animate.for) that I have modified to show this.

Here is the full code - you can see the change at the end of the routine 'assemble_list'


  •                            *
    
  •  Trial OPENGL program      *
    
  •                            *
    

  subroutine spinDisplay(spin)
  include <opengl.ins>,nolist
  include <clearwin.ins>,nolist
  double precision spin
  logical do_draw
  common /animate_com/ do_draw
  if (do_draw)then
    call glClear (OR(GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT))
    call glMatrixMode (GL_MODELVIEW)
    call glLoadIdentity()
    call glTranslated(0d0,0d0,-10d0)
    call glRotated(spin,1d0,0d0,0d0)
    call glCallList(101)
    spin=spin+2d0
    call swap_opengl_buffers() 
  endif
  call temporary_yield@()
  end

  subroutine spinSlab()
  logical do_draw
  common /animate_com/ do_draw
  data do_draw/.TRUE./
  do_draw=.TRUE.
  end

  subroutine stopSlab()
  logical do_draw
  common /animate_com/ do_draw
  do_draw=.FALSE.
  end

  subroutine assemble_list
  include <clearwin.ins>,nolist
  include <opengl.ins>,nolist
  real*4 white_colour(4), grey_colour(4), dark_grey_colour(4)
  real*4 red_colour(4), yellow_colour(4), green_colour(4)
  real*4 blue_colour(4), purple_colour(4), cyan_colour(4)
  real*8 dimension,scale,d,fd,front,back
  integer flags,k
  integer hdc
  logical ok     
  external opengl_proc
  data white_colour/1.0,1.0,1.0,1.0/
  data grey_colour/0.5,0.5,0.5,1.0/
  data dark_grey_colour/0.3,0.3,0.3,1.0/
  data red_colour/1.0,0.0,0.0,1.0/
  data yellow_colour/1.0,1.0,0.0,1.0/
  data green_colour/0.0,1.0,0.0,1.0/
  data blue_colour/0.0,0.0,1.0,1.0/
  data purple_colour/1.0,0.0,1.0,1.0/
  data cyan_colour/0.0,1.0,1.0,1.0/
  data front,back/-0.01d0,-0.5d0/

  call glEnable(GL_DEPTH_TEST)
  hDC=clearwin_info@('OPENGL_DEVICE_CONTEXT')
  call glColor3f(1.0,1.0,1.0)

  ok=wglUseFontOutlines(hDC, 0, 255, 1000, 0.0, 0.1,
 &amp;                     WGL_FONT_POLYGONS,core4(0))
 
  call glMatrixMode (GL_MODELVIEW)
  call glLoadIdentity()
  call glTranslated(0d0,0d0,-10d0)

C C Clear the color and depth buffers. C call glClear (OR(GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT)) dimension=2.2d0 scale=dimension*0.9d0 call glDisable(GL_LIGHTING)

  call glNewList(101,GL_COMPILE)

C Front face call glBegin(GL_POLYGON) call glColor3fv(blue_colour) call glVertex3d(-dimension,-dimension,front) call glVertex3d(-dimension, dimension,front) call glVertex3d( dimension, dimension,front) call glVertex3d( dimension,-dimension,front) call glEnd() C Back face
call glBegin(GL_POLYGON) call glColor3fv(yellow_colour) call glVertex3d(-dimension,-dimension,back) call glVertex3d( dimension,-dimension,back) call glVertex3d( dimension, dimension,back) call glVertex3d(-dimension, dimension,back) call glEnd() C Top face call glBegin(GL_POLYGON) call glColor3fv(red_colour) call glVertex3d(-dimension, dimension,front) call glVertex3d(-dimension, dimension,back) call glVertex3d( dimension, dimension,back) call glVertex3d( dimension, dimension,front) call glEnd() C Bottom face call glBegin(GL_POLYGON) call glColor3fv(green_colour) call glVertex3d( dimension,-dimension,front) call glVertex3d( dimension,-dimension,back) call glVertex3d(-dimension,-dimension,back) call glVertex3d(-dimension,-dimension,front) call glEnd() C C Draw graph C call glBegin(GL_LINES) call glColor3fv(white_colour) call glVertex2d(-scale,0d0) call glVertex2d(scale,0d0) call glVertex2d(0d0,-scale) call glVertex2d(0d0,scale) k=-10 while(k .LE. 10) do call glVertex2d((scale/10)k,0.0d0) call glVertex2d((scale/10)k,0.1d0) call glVertex2d(0.0d0,(scale/10)k) call glVertex2d(0.1d0,(scale/10)k) k=k+1 endwhile call glEnd() call glColor3fv(red_colour) call glBegin(GL_LINE_STRIP) d=-10d0 while(d .LT. 10d0)do fd=5(d/10)3+3(d/10)**2-d/10 call glVertex2d(dscale/10,fdscale/10) d=d+0.05d0 endwhile call glEnd() call glColor3fv(green_colour) call glBegin(GL_LINE_STRIP) d=-10d0 while(d .LT. 10)do fd=5(d/10)3+6(d/10)**2-d/10 call glVertex2d(dscale/10,fdscale/10) d=d+0.05d0 endwhile call glEnd() call glColor3fv(red_colour) call glListBase (1000) call glTranslated(0.15d0,scale*0.95,0d0) call glScaled(0.2d0,0.2d0,0.2d0) call glCallLists (5, GL_UNSIGNED_BYTE, '+10.0')

c*** Change- add some fixed text
call glLoadIdentity()
call glMatrixMode (GL_MODELVIEW) call glTranslated(-2.5d0,0d0,-10d0) call glcolor3d(1d0,0d0,0d0) call glDisable(GL_DEPTH_TEST)
call glCallLists (11, GL_UNSIGNED_BYTE,'Hello World') call glEnable(GL_DEPTH_TEST) c*** end ofchange
call glEndList() end

  subroutine myinit()
  call assemble_list()
  end

  subroutine myreshape(w,h)
  include <opengl.ins>,nolist
  integer w
  integer h
  double precision aspect_ratio
                 
  if(h.NE.0)then
    aspect_ratio=dble(w)/h
    call glMatrixMode (GL_PROJECTION)
    call glLoadIdentity ()
    call gluPerspective (30.0d0,aspect_ratio,1d0,15d0)
    call glViewport(0,0,w,h)
  endif
  end

  integer function opengl_proc()
  include <clearwin.ins>,nolist
  include <opengl.ins>,nolist
  character*256 reason
  integer w,h
  reason=clearwin_string@('CALL_BACK_REASON')
  if(reason.EQ.'SETUP')then
    call myinit()
  else if(reason.EQ.'RESIZE')then
    w=clearwin_info@('OPENGL_WIDTH')
    h=clearwin_info@('OPENGL_DEPTH')
    call myreshape(w,h)
  else if(reason.EQ.'MOUSE_LEFT_CLICK')then
    call spinSlab()
  else if(reason.EQ.'MOUSE_RIGHT_CLICK')then
    call stopSlab()
  endif
  opengl_proc=2
  end

  program Animate
  include <clearwin.ins>,nolist
  include <opengl.ins>,nolist
  double precision spin
  integer i,window
  integer opengl_proc
  external opengl_proc
  i=winio@('%es%ca[Rotating Slab]&amp;')
  i=winio@('%fn[Times New Roman]%ts&amp;',3.0d0)
  i=winio@('%sp%ww[no_border]%pv%^og[double,depth16]%lw'
 &amp;         ,0,0,650,650,opengl_proc,window)

  spin=0d0
  while(window .LT. 0)do
    call spinDisplay(spin)
  endwhile
  end
30 May 2021 3:07 #27882

C Draw graph C call glBegin(GL_LINES) call glColor3fv(white_colour) call glVertex2d(-scale,0d0) call glVertex2d(scale,0d0) call glVertex2d(0d0,-scale) call glVertex2d(0d0,scale) k=-10 while(k .LE. 10) do call glVertex2d((scale/10)k,0.0d0) call glVertex2d((scale/10)k,0.1d0) call glVertex2d(0.0d0,(scale/10)k) call glVertex2d(0.1d0,(scale/10)k) k=k+1 endwhile call glEnd() call glColor3fv(red_colour) call glBegin(GL_LINE_STRIP) d=-10d0 while(d .LT. 10d0)do fd=5(d/10)3+3(d/10)**2-d/10 call glVertex2d(dscale/10,fdscale/10) d=d+0.05d0 endwhile call glEnd() call glColor3fv(green_colour) call glBegin(GL_LINE_STRIP) d=-10d0 while(d .LT. 10)do fd=5(d/10)3+6(d/10)**2-d/10 call glVertex2d(dscale/10,fdscale/10) d=d+0.05d0 endwhile call glEnd() call glColor3fv(red_colour) call glListBase (1000) call glTranslated(0.15d0,scale*0.95,0d0) call glScaled(0.2d0,0.2d0,0.2d0) call glCallLists (5, GL_UNSIGNED_BYTE, '+10.0')

c*** add some fixed text
call glLoadIdentity()
call glMatrixMode (GL_MODELVIEW) call glTranslated(-2.5d0,0d0,-10d0) call glcolor3d(1d0,0d0,0d0) call glDisable(GL_DEPTH_TEST)
call glCallLists (11, GL_UNSIGNED_BYTE,'Hello World') call glEnable(GL_DEPTH_TEST) c*** end ofchange
call glEndList() end

  subroutine myinit()
  call assemble_list()
  end

  subroutine myreshape(w,h)
  include <opengl.ins>,nolist
  integer w
  integer h
  double precision aspect_ratio                    
  if(h.NE.0)then
    aspect_ratio=dble(w)/h
    call glMatrixMode (GL_PROJECTION)
    call glLoadIdentity ()
    call gluPerspective (30.0d0,aspect_ratio,1d0,15d0)
    call glViewport(0,0,w,h)
  endif
  end

  integer function opengl_proc()
  include <clearwin.ins>,nolist
  include <opengl.ins>,nolist
  character*256 reason
  integer w,h
  reason=clearwin_string@('CALL_BACK_REASON')
  if(reason.EQ.'SETUP')then
    call myinit()
  else if(reason.EQ.'RESIZE')then
    w=clearwin_info@('OPENGL_WIDTH')
    h=clearwin_info@('OPENGL_DEPTH')
    call myreshape(w,h)
  else if(reason.EQ.'MOUSE_LEFT_CLICK')then
    call spinSlab()
  else if(reason.EQ.'MOUSE_RIGHT_CLICK')then
    call stopSlab()
  endif
  opengl_proc=2
  end

  program Animate
  include <clearwin.ins>,nolist
  include <opengl.ins>,nolist
  double precision spin
  integer i,window
  integer opengl_proc
  external opengl_proc
  i=winio@('%es%ca[Rotating Slab]&amp;')
  i=winio@('%fn[Times New Roman]%ts&amp;',3.0d0)
  i=winio@('%sp%ww[no_border]%pv%^og[double,depth16]%lw'
 &amp;         ,0,0,650,650,opengl_proc,window)
  spin=0d0
  while(window .LT. 0)do
    call spinDisplay(spin)
  endwhile
  end
30 May 2021 10:42 #27883

Thank you very much. This was by the way the best ever Silverfrost example on which i learned OpenGL, glad you took it. If Silverfrost made 20-30 such examples 25 years ago this board would have also OpenGL discussion topic attracting more people to Fortran. It is very useful in modern world of 3D data visualization and presentation. It also together with Clearwin removes words 'obsolete' and 'boring' from Fortran. If you have more examples of use of OpenGL with Fortran please publish

5 Jun 2021 10:34 #27895

FLEXPLAN3D, Trying to adopt for my own use, two more problems i did not solve with this specific demo in years, i do not know if they are easy or not.

  1. How to change the main background on which this entire plot was done from black to other color ?

  2. and this was specifically hard and any attempts i tried failed: how to put numbering near each tic on each axis, not just one marked as 10 ?

Thanks in advance if you will find time to try

6 Jun 2021 5:22 #27899

Dan

To set the background use GLCLEARCOLOR

e.g. dark to set a dark red background

CALL GLCLEARCOLOR (0.5,0.0,0.0, 1.0).

Here is a 2nd mod to the assemble_list routine in the animate.for example. I think it best to handle all text after drawing all the lines

. . C Clear the color and depth buffers. C call glClear (OR(GL_COLOR_BUFFER_BIT,GL_DEPTH_BUFFER_BIT)) c**** code addition to set background to dark red
CALL GLCLEARCOLOR (0.5,0.0,0.0, 1.0) c*** end set background . . . . c**** draw the 2 graph traces call glColor3fv(red_colour) call glBegin(GL_LINE_STRIP) d=-10d0 while(d .LT. 10d0)do fd=5*(d/10)3+3(d/10)**2-d/10 call glVertex2d(dscale/10,fdscale/10) d=d+0.05d0 endwhile call glEnd() call glColor3fv(green_colour) call glBegin(GL_LINE_STRIP) d=-10d0 while(d .LT. 10)do fd=5(d/10)3+6(d/10)**2-d/10 call glVertex2d(dscale/10,fd*scale/10) d=d+0.05d0 endwhile call glEnd()

c*** additional code to label the y-axis call glColor3fv(white_colour) call glListBase (1000) call glScaled(0.1d0,0.1d0,0.1d0) k=-10 while(k .LE. 10) do call glpushmatrix() call glTranslated(1d0,dble(k)2d0,0d0) write(str,100)float(k) 100 format(f5.1) call glCallLists (5, GL_UNSIGNED_BYTE, str(1:5)) call glpopmatrix() k=k+1 endwhile c** end of y-axis labelling

c*** add some fixed text
call glLoadIdentity()
call glMatrixMode (GL_MODELVIEW) call glTranslated(-2.5d0,0d0,-10d0) call glcolor3d(1d0,0d0,0d0) call glDisable(GL_DEPTH_TEST)
call glCallLists (11, GL_UNSIGNED_BYTE,'Hello World') call glEnable(GL_DEPTH_TEST) c*** end ofchange
call glEndList() end

P.s. are you really in the Antarctic ?

7 Jun 2021 12:54 #27900

Quoted from FLEXPLAN3D

P.s. are you really in the Antarctic ?

As somebody said: “The coldest winter I ever spent was a summer in San Francisco.” Northern California is like Antarctica because perception of cold is often psychological. In Antarctica or Siberia it's cold but you are prepared for that, and it is cold just outside but very warm in the buildings. In Northern CA it is always cold ocean, cold evenings, homes are not energy efficient. And in my particular area also 5x more expensive to heat the homes because of being on the hills and 10 miles from the cities we have to use liquid propane gas for that instead of cheap natural one. Just yesterday stopped using infrared electric heaters surrounding computer chair. And also IR sauna, our savior, which even cats love to stay in:). Hope the solar collectors will completely solve this damn problem of heating atmosphere by literally burning thousands of dollar bills. What buzzing me is that on the home and backyard falls ~0.5 Megawatt of solar power, 50 times more than needed, and i still can not find suitable way to get it.

And many thanks for the solution of OpenGL problems, all works great!

20 Jul 2023 10:29 #30462

FLEXPLAN3D,

Can you please comment is this a norm that

  1. It takes substantial time ~10-20 seconds to load and plot 20-40 million polygons ?

  2. The Video RAM my card uses is 24GB and i can not plot more than 40M polygons. Nothing is crashing or freezing program but you just get nothing plotted. It does not look like the 40M polygons takes a lot of video RAM. Actually this could be even less than 1 GB probably. I may not need to plot 40M polygons often, which is a lot, but it would be good not to worry permanently about hitting limits (number of particles sometimes reach 100s of millions, each needs at least one polygon, and soon typical will be billions) and get too slow plotting speed.

  3. When switched from 3 generation prior videocard NVIDIA RTX 750 to NVIDIA RTX3090 i have not seen huge speed plotting boost despite 1-2 orders larger number of cores. Actually the speed almost not changed. The only seems changed is that i can get more polygons plotted because of 4x size of VideoRAM in new card. Was this lack of huge boost because of PCIe speed limits? Unlikely. Is this due to the drivers are not good? Or may be Fortran slowed things somewhere ?

Please login to reply.