forums.silverfrost.com Forum Index forums.silverfrost.com
Welcome to the Silverfrost forums
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

user_surface and select_graphics_object@
Goto page 1, 2  Next
 
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> ClearWin+
View previous topic :: View next topic  
Author Message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Thu Mar 15, 2012 5:05 am    Post subject: user_surface and select_graphics_object@ Reply with quote

Paul,

I have tried to combine user_surface and select_graphics_object@ and have not been successful.
I have checked the relationship betweet the pointer to the graphics memory and the use of virtual windows and can confirm that the
pointer is not updated when a virtual screen is selected.

I obtain the pointer to the graphics memory using %gr with:
Code:

      i = winio@ ('%ca@&', caption)
      i = winio@ ('%ww[no_border]&')
      i = winio@ ('%sc&', plot_setup_func)                  ! call saplot setup function
      i = winio@ ('%pv&')
!
      i = winio@ ('%`^gr[grey, user_resize, rgb_colours, full_mouse_input, user_surface]&',  &
                    1024, 768,          &   ! screen dimension when not maximised
                    ptr_RGB_Address,    &   ! screen address for rgb surface ( not sure of the order ? )
                    w_handle,           &   ! ` window handle defined in crtstart
                    mouse_back_func)        ! ^ call back function for mouse and resize
!
      i = winio@ ('%mg&', WM_MOUSEWHEEL, OnMouseWheel)      ! mousewheel response
!
      call Plot_Menus
!
      i = winio@ ('%hw', hwnd)                              ! return the handle of the current window.

I then select the virtual screen with:
Code:

      call get_graphical_resolution@ ( w_width, w_depth )
      write (98,9000) 'Returned graphics window size', w_width, w_depth
      write (98,9001) 'pointer for RGB direct addressing ', ptr_RGB_Address
!
      NXPIX         = MIN (HDFLAG,MXZBUF)      ! limit for zbuffer
      X_MAX_WIN     = nxpix - 1
      Y_MAX_WIN     = X_MAX_WIN * ASPECT_WIN
      NYPIX         = Y_MAX_WIN + 1
!
      i = create_graphics_region@ (hd_handle, nxpix, nypix)
      i = select_graphics_object@ (hd_handle)
!
      call draw_filled_rectangle@ (0,0, nxpix-1,nypix-1, rgb@ (50,50,50))
!
      write (98,9003) 'Revised graphics size ', nxpix, nypix
      write (98,9004) 'pointer for RGB direct addressing ', ptr_RGB_Address

This reports:
Code:

<Real   _SCREEN> :Returned graphics window size X=1234 Y= 847
<Real   _SCREEN> :pointer for RGB direct addressing 1152778240

<VIRTUAL_SCREEN> :Revised graphics size  X=2048 Y=1358
<VIRTUAL_SCREEN> :pointer for RGB direct addressing 1152778240

I then try to check the graphics object using "ptr_RGB_Address"
Code:

      call GET_GRAPHICAL_RESOLUTION@ ( WIDTH, HEIGHT )
!
      iw = clearwin_info@ ('GRAPHICS_WIDTH')
      id = clearwin_info@ ('GRAPHICS_DEPTH')
      jw = ((3*iw+3)/4)*4
!
      do ver = 0,height-1
         do hor = 0,width-1
!
!         get colour from direct addressing
            jj = ptr_RGB_Address + hor*3 + ver*jw
            rgb_i(1) = core1(jj)   ; if (rgb_i(1) < 0) rgb_i(1) = rgb_i(1)+256   ! blue
            rgb_i(2) = core1(jj+1) ; if (rgb_i(2) < 0) rgb_i(2) = rgb_i(2)+256   ! green
            rgb_i(3) = core1(jj+2) ; if (rgb_i(3) < 0) rgb_i(3) = rgb_i(3)+256   ! red
            rgb_all  = rgb_i(3) + 256*(rgb_i(2) + 256*rgb_i(1))
!
            call GET_RGB_VALUE@ ( HOR, VER, VALUE )
            if (rgb_all /= value) then
               write ( *,*) hor,ver, rgb_i, rgb_all, value, ' Change RGB'
               write (98,*) hor,ver, rgb_i, rgb_all, value, ' Change RGB'
               n_e = n_e + 1
            else
               n_s = n_s + 1
            end if

This indicates that the user_surface address is not pointing to the selected graphics objec
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Thu Mar 15, 2012 7:57 am    Post subject: Reply with quote

Lost the last part of my previous post !!

To be able to address virtual screens, would it be possible to have a routine like:

get_selected_graphics_object_address@ (Byte_Address, WIDTH, HEIGHT, NBBP, ERCODE )

where “NBBP” (the number of bits per pixel) could be adapted to indicate the memory storage format, if required. I understand user_surface ensures that BGR storage is provided.

Also, can I address the memory directly via ?
Code:

   call get_selected_graphics_object_address@ (Byte_Address, WIDTH, HEIGHT, NBBP, ERCODE )
   jw = ((width*3+3)/4)*4
 
   call process_surface ( Core1(Byte_Address), WIDTH, HEIGHT, jw)

   subroutine process_surface ( surface, WIDTH, HEIGHT, jw)
    integer*4 WIDTH, HEIGHT, jw
    integer*1 surface(jw,height)

This would require knowledge of the different storage methods if the user_surface and create_graphics_region@ do use different storage methods ?

Please let me know if this approach is possible ?

John
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Wed Mar 21, 2012 12:25 pm    Post subject: Reply with quote

John

I have seen your post but I have not yet had time to investigate.

Paul
Back to top
View user's profile Send private message AIM Address
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Tue Apr 10, 2012 3:20 pm    Post subject: Reply with quote

I can modify the ClearWin+ library so the "user_surface" pointer is associated with the selected graphics object and I can provide a routine to get this value for the currently selected graphics object.

WIDTH and HEIGHT could also be returned but these should be known to the programmer. NBBP does not appear to be variable. For simplicity I would just provide access to the "user_surface" pointer.

I would have to send you a trial DLL for you to test if this works as we would hope/expect.

The following program, taken from the help file, illustrates how this works. The related pointer will change after a resize event.

Code:
      WINAPP
       INCLUDE <windows.ins>
       EXTERNAL draw
       INTEGER ptr
       COMMON ptr
       ia=winio@('%ww%pv%^gr[black,user_resize,user_surface]',256,256,ptr,draw)
      END

      INTEGER FUNCTION draw()
       INCLUDE <windows.ins>
       INTEGER ptr
       COMMON ptr
       INTEGER width,depth,m,i,q,x,y,full_on,pad_width
       IF(clearwin_info@('graphics_resizing').eq.1)THEN
         width=clearwin_info@('graphics_width')
         depth=clearwin_info@('graphics_depth')
         m=MIN(width,depth)
!--   Calculate width in bites of one row remembering to round up to nearest 4 bytes
         pad_width=ls(rs(3*width+3,2),2)
!--   Draw a diagonal yellow line
         DO i=1,m
             x=i-1
             y=i-1
!--       Compute index into array
             q=3*x+pad_width*y
             full_on=255
!--       Red component
             CORE1(ptr+q+2)=full_on
!---       Green component
             CORE1(ptr+q+1)=full_on
         ENDDO
       ENDIF
       draw=2
      END
Back to top
View user's profile Send private message AIM Address
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Tue Apr 10, 2012 3:36 pm    Post subject: Reply with quote

Maybe I would provide a modified CREATE_GRAPHICS_REGION@ that returns the pointer instead of the value 1 on success.
Back to top
View user's profile Send private message AIM Address
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Wed Apr 11, 2012 1:19 am    Post subject: Reply with quote

Paul,

Thanks for the idea. It sounds like a good approach.
It might be good if select_graphics_object@ also returned the address.

There are two items which need more clarification.

1) window resolution:
call GET_GRAPHICAL_RESOLUTION@ ( WIDTH, HEIGHT ) ! this appears to return the resolution of the selected object, while

The following calls appear to return the resolution of only the primary graphics window.
iw = clearwin_info@ ('GRAPHICS_WIDTH') ! primary object
id = clearwin_info@ ('GRAPHICS_DEPTH')
I might be wrong in this interpretation, but it appeared this way on a recent test.

2) RGB or BGR ?
The colour order for the primary window is BGR, while a returned DIB is RGB. What is the order for the CREATE_GRAPHICS_REGION@ ?

There is a bit of duplication between the supplied window handle and the returned window address. There can also be confusion as to if the handle is supplied ( create_graphics_region@ or %gr`) or returned in other cases (can't recall at the moment !!) Is there potential to clean up this difference, with a handle being supplied and an address being returned ?

I would look forward to testing this new returned address out. It would be good to incorporate this with the gif colour palette routines that Robert has supplied as I am using all this functionality in my .gif file dump from the selected graphics object.

John
Back to top
View user's profile Send private message
DanRRight



Joined: 10 Mar 2008
Posts: 2813
Location: South Pole, Antarctica

PostPosted: Fri Apr 13, 2012 12:23 pm    Post subject: Reply with quote

BTW, why you need user_surface?

Here are my 2 cents with finding graphics parameters. Some other ways i remember were not working reliably unless things changed over last several years.

Reiably system resolution of main monitor i get with (you need "use mswin")
iSysXRES = GetSystemMetrics(SM_CXSCREEN)
iSysYRES = GetSystemMetrics(SM_CYSCREEN)

The resolution of active graphics window get with
call get_graphical_resolution@(lx_GrWindow,ly_GrWindow)

The location of existing graphics windows i find with
igrObjExist=SELECT_GRAPHICS_OBJECT@(ihwGrWindowActive)
call GET_WINDOW_LOCATION@(ihwGrWindowActive, ix0MainGraphWinpos,iy0MainGraphWinpos, lx_GrWindow, ly_GrWindow)


Last edited by DanRRight on Fri Apr 13, 2012 4:48 pm; edited 2 times in total
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Fri Apr 13, 2012 3:42 pm    Post subject: Reply with quote

This did not work out as I expected but after a lot of messing about I have managed to provide for one alternative user surface for a given %gr.

Here is how it will work but the side-effects will be confusing...

Code:
      WINAPP
       INCLUDE <windows.ins>
       INTEGER ptr,ptr1,ictrl,hw,hdc
       ia=winio@('%ww&')
       ia=winio@('%gr[black,user_surface]&',256,256,ptr)
       ia=winio@('%lc&', hw)
       ia=winio@('%lw',ictrl)
       !Draw a red diagonal line.
       call draw(ptr,256,256,RGB@(255,0,0))
       call window_update@(ptr)
       ia=winio@('%bt[Show alternative surface]')
       !Keep the initial ptr because user_surface@ overwrites it.
       ptr1 = ptr
       !Zero arguments create an alternative user surface and the old hdc is returned.
       hdc = user_surface@(hw, 0, 0)
       !Draw a green diagonal line
       call draw(ptr,256,256,RGB@(0,255,0))
       call window_update@(ptr)
       ia=winio@('%bt[Show first surface]')
       !Restore the original surface by passing the corresponding hdc and ptr which was saved as ptr1
       hdc = user_surface@(hw, hdc, ptr1)
       call window_update@(ptr)
      END

      SUBROUTINE draw(ptr,width,depth,colr)
       INTEGER ptr,width,depth,colr,m,i,q,x,y,pad_width
       INTEGER r,g,b
       m = MIN(width,depth)
       pad_width = LS(RS(3*width+3,2),2)
       r = IAND(colr,255)
       colr = ISHFT(colr,-8)
       g = IAND(colr,255)
       colr = ISHFT(colr,-8)
       b = colr
       DO i=1,m
         x = i-1
         y = i-1
         q=3*x+pad_width*y
         CORE1(ptr+q+2) = r
         CORE1(ptr+q+1) = g
         CORE1(ptr+q)   = b
       ENDDO
      END
Back to top
View user's profile Send private message AIM Address
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Sun Apr 15, 2012 3:06 am    Post subject: Reply with quote

Paul,

Thanks very much for your response.

Previous use of multiple windows/regions has been via the user supplied handle.
My experience is limited to creating windows via %gr or create_graphics_region@.
Different windows are managed via select_graphics_object@.

I have previously raised questions regarding:
1) rgb vs bgr colour sequence,
2) retreiving selected window dimension.
Both of these can be readily overcome as they only need to be documented and identify the appropriate routines for virtual windows created by create_graphics_region@

My preference is to call draw with " call draw (core1(ptr),256,256,RGB@(0,255,0)) " This way there is limited use of core1 and draw can be more standard fortran.

Resize is a special case for the address of visable windows, which is presently covered.

I am assuming you are proposing an alternative selection via "user_surface@",
which supplies more information, including the address, then that would be a good help. I could not find it in the Help. (Please let me know if I am wrong in this interpretation.)
If this is the case, it would be good to test this approach in my code where I analyse the colours of either a window or virtual region.
I have a graphics application where I can create a higher resolution output to a .gif file.
I have had problems with the colour palette and also the size of the region. (screen graphics beyond 2048 is likely soon)
These changes may be able to improve this performance.

Also, I would also like to understand what the side-effects may be.

I look forward to what you may be able to provide.

John
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Sun Apr 15, 2012 7:16 am    Post subject: Reply with quote

John

I am now not clear about what you are asking for so I will complete the work that I have started (on what I thought to wanted) and send it to you.

Previously ClearWin+ allowed only one %gr[user_surface] (i.e. one internal pointer supplied to the programmer via %gr[user_surface]). When using this pointer to draw directly to the surface the programmer needs to use the bgr order. This is illustrated in the sample above.

So far I have modified ClearWin+ so that one %gr can now have more than one selectable user_surface. I am now thinking that there is a more general approach that will also allow for more than one %gr to have a user_surface. I will implement both and get back to you.

Paul
Back to top
View user's profile Send private message AIM Address
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Sun Apr 15, 2012 2:39 pm    Post subject: Reply with quote

Paul,
My present understanding of multiple graphics regions in memory is:
The main graphics window (from %gr) is stored in both the graphics card memory and normal memory. It has the attributes of a handle, width, height and a memory address. This graphics surface can be reviewed and modified using direct addressing via CORE1(ptr+offset). An important attribute of this surface is that the memory address can vary due to resize so the address value can change.
I also make use of virtual windows to store other graphics images. These are created via “create_graphics_region@ (handle(ii), nxpix, nypix)” and can be selected for drawing to via “select_graphics_object@ (handle(ii))”. Parts of them can be displayed using "copy_graphics_region@" to the %gr graphics surface. These windows have the attributes of handle, width and height, but not a memory address, even though these are stored in memory.
What I want is to have direct manipulation of these virtual graphics objects. This address could then be used to manipulate the graphics object, similar to direct addressing of the %gr graphics surface.
I also suggested to be able to use this memory address as a key identifier of each graphics surface, although this may duplicate the use of the graphics_region’s handle. It may not be necessary to be able to do this as this can be done via “get_graphical_resolution@” of the selected graphics object, or “GET_WINDOW_LOCATION@” if the appropriate HANDLE is available.
Your example appears to show that the selected (displayed) graphics object can be updated via “perform_graphics_update@()” or “window_update@ (address_ptr)” using the memory address.
What I want to do is address these virtual graphics windows in a similar way to direct memory addressing of the %gr window using the CORE1 addressing. At present I need to do this to review the colour palette of the graphics region, before sending it to a .gif file.
The larger virtual images I create in background are not to be displayed, but only generated then dumped to a .gif file. I was interested in the DIB option as it gave direct addressing, but X size has been limited to 2048.
Two different colour storage methods are used; %gr uses BGR, while DIB uses RGB. I am not sure what method is used for create_graphics_region@, which has been the reason for this question in the past.
The short answer to what I have been asking is: I want create_graphics_region@ to return the memory address of the graphics region storage so that it can be manipulated via CORE1. This address can be in the range of 0:4gb, which may give some problems for error return.
I alternatively suggested that a variation of “select_graphics_object@ could return the address and other attributes of the graphics identified by the (user supplied) handle.
My apology if this is a long response. I would be pleased to comment further where required.
John
Back to top
View user's profile Send private message
DanRRight



Joined: 10 Mar 2008
Posts: 2813
Location: South Pole, Antarctica

PostPosted: Mon Apr 16, 2012 3:49 am    Post subject: Reply with quote

John,
Are you sure DIB is restricted to 2048? I just checked it loaded 3648x2736 image
Back to top
View user's profile Send private message
JohnCampbell



Joined: 16 Feb 2006
Posts: 2554
Location: Sydney

PostPosted: Mon Apr 16, 2012 4:43 am    Post subject: Reply with quote

Dan,

See the earlier post on DIB_BLOCK Limits, as it identifies a problem retrieving a graphics region into a DIB_Block.
I am trying to find a way of quickly reviewing a graphics region to modify the colour palette, before dumping to a .gif file.
Direct addressing appears to be the best approach, as I only change about 0.1% of the pixels.
Thanks very much for your comments,

John
Back to top
View user's profile Send private message
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Mon Apr 16, 2012 8:59 am    Post subject: Reply with quote

John

%gr[user_surface] is based on a call to CreateDIBSection and this provides a pointer to the associated memory block. Otherwise %gr is based on a call to CreateCompatibleBitmap which has no direct memory addressing. This means that direct memory addressing is only available via %gr[user_surface].

create_graphics_region@ mirrors %gr (without user_surface) in that it is also based on a call to CreateCompatibleBitmap. I could provide a modified version of create_graphics_region@ (that calls CreateDIBSection rather than CreateCompatibleBitmap) but I doubt this would meet your needs.

Sadly I have come to the conclusion that what you are asking for is either not possible or would require extensive programming.
Back to top
View user's profile Send private message AIM Address
PaulLaidler
Site Admin


Joined: 21 Feb 2005
Posts: 7916
Location: Salford, UK

PostPosted: Mon Apr 16, 2012 11:39 am    Post subject: Reply with quote

Although this is not what John wants, I have tidied up what I have done so that it will work in the following way.

Code:
      WINAPP
       INCLUDE <windows.ins>
       INTEGER ptr,ptr1,ictrl,hw,hdc,hdc1
       ia=winio@('%ww&')
       ia=winio@('%gr[black,user_surface]&',256,256,ptr)
       hdc = clearwin_info@("GRAPHICS_HDC")
       ia=winio@('%lc&', hw)
       ia=winio@('%lw',ictrl)
       !Draw a red diagonal line.
       call draw(ptr,256,256,RGB@(255,0,0))
       call window_update@(ptr)
       !Create a virtual surface and draw a green diagonal line
       call create_user_surface@(256, 256, hdc1, ptr1)
       call draw(ptr1,256,256,RGB@(0,255,0)) 
       ia=winio@('%bt[Show alternative surface]')
       ia = select_user_surface@(hw, hdc1, ptr1)
       call window_update@(ptr1)
       !Restore the original surface
       ia=winio@('%bt[Show first surface]')
       ia = select_user_surface@(hw, hdc, ptr)
       call window_update@(ptr)
      END

      SUBROUTINE draw(ptr,width,depth,colr)
       INTEGER ptr,width,depth,colr,m,i,q,x,y,pad_width
       INTEGER r,g,b
       m = MIN(width,depth)
       pad_width = LS(RS(3*width+3,2),2)
       r = IAND(colr,255)
       colr = ISHFT(colr,-8)
       g = IAND(colr,255)
       colr = ISHFT(colr,-8)
       b = colr
       DO i=1,m
         x = i-1
         y = i-1
         q=3*x+pad_width*y
         CORE1(ptr+q+2) = r
         CORE1(ptr+q+1) = g
         CORE1(ptr+q)   = b
       ENDDO
      END
Back to top
View user's profile Send private message AIM Address
Display posts from previous:   
Post new topic   Reply to topic    forums.silverfrost.com Forum Index -> ClearWin+ All times are GMT + 1 Hour
Goto page 1, 2  Next
Page 1 of 2

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group