|
forums.silverfrost.com Welcome to the Silverfrost forums
|
View previous topic :: View next topic |
Author |
Message |
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Thu Mar 15, 2012 5:05 am Post subject: user_surface and select_graphics_object@ |
|
|
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 |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Thu Mar 15, 2012 7:57 am Post subject: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Wed Mar 21, 2012 12:25 pm Post subject: |
|
|
John
I have seen your post but I have not yet had time to investigate.
Paul |
|
Back to top |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Tue Apr 10, 2012 3:20 pm Post subject: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Tue Apr 10, 2012 3:36 pm Post subject: |
|
|
Maybe I would provide a modified CREATE_GRAPHICS_REGION@ that returns the pointer instead of the value 1 on success. |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Wed Apr 11, 2012 1:19 am Post subject: |
|
|
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 |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2816 Location: South Pole, Antarctica
|
Posted: Fri Apr 13, 2012 12:23 pm Post subject: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Fri Apr 13, 2012 3:42 pm Post subject: |
|
|
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 |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Sun Apr 15, 2012 3:06 am Post subject: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Sun Apr 15, 2012 7:16 am Post subject: |
|
|
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 |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Sun Apr 15, 2012 2:39 pm Post subject: |
|
|
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 |
|
|
DanRRight
Joined: 10 Mar 2008 Posts: 2816 Location: South Pole, Antarctica
|
Posted: Mon Apr 16, 2012 3:49 am Post subject: |
|
|
John,
Are you sure DIB is restricted to 2048? I just checked it loaded 3648x2736 image |
|
Back to top |
|
|
JohnCampbell
Joined: 16 Feb 2006 Posts: 2554 Location: Sydney
|
Posted: Mon Apr 16, 2012 4:43 am Post subject: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Mon Apr 16, 2012 8:59 am Post subject: |
|
|
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 |
|
|
PaulLaidler Site Admin
Joined: 21 Feb 2005 Posts: 7925 Location: Salford, UK
|
Posted: Mon Apr 16, 2012 11:39 am Post subject: |
|
|
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 |
|
|
|
|
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
|