English Amiga Board


Go Back   English Amiga Board > Coders > Coders. System

 
 
Thread Tools
Old 22 March 2023, 13:01   #1
mateusz_s
Registered User
 
Join Date: Jan 2020
Location: Poland
Posts: 181
[WB, RTG, Window] Rendering graphics to wb public window

Hi,
I am adapting my Raycaster project to display its output in different modes.
So far I am finished with Fullscreen RTG and HAM8 modes.

I also want the option to show the output on public WB window (when the WB is in RTG mode). And I got couple of issues. Maybe you can help me a bit.

Issue no #1
So to copy my output frame buffer to wb public window I am using:

Code:
WritePixelArray(output_buffer_32, 0, 0, bytes_per_row, FRM_window->RPort, 0, 0, output_width, output_height, output_pixel_format );
The result is OK like below:



So basically everythying is working OK. But this is just a single buffer rendering, so I have the screen tearing inside the game.
I am not sure how to make double or triple buffer. Because when using WritePixelArray(..) I am blitting to the Window Rastport.
In my other cases (fullscreen 32bit and ham8) I was switching the screen bitmaps.

How can I add second or third buffer? And how can I have synced blitting using two buffers. In previurs modes I was using RethinkDisplay() for double buffering with success. I am not sure what to do in this case - I mean I got only public window without the screen.


Issue no #2
How can I protect the cursor not to leave my window?
I can move mouse free to move the view, but if the cursor will be outside my window,
and I press "left-button" I will lost the focus from my window and I will "back" to workbench.


I am attaching part of my code.

- Creating Public WB Window -

Code:
UBYTE FRM_Init_WB_Window()
{
    // Get the size of WB screen to set the new window in the middle of the screen.
    ULONG win_x_pos = 10, win_y_pos = 10;

    struct Screen* pubscreen = LockPubScreen(NULL); 
    if (pubscreen != NULL)
    {
        win_x_pos = (pubscreen->Width - FRM_requested_width) / 2;
        win_y_pos = (pubscreen->Height - FRM_requested_height) / 2;
        UnlockPubScreen(NULL, pubscreen);
    }

    FRM_Console_Write("\nOpening window: ");

	// Create full screen window on screen.
	FRM_window = OpenWindowTags(        NULL,
										WA_Left, win_x_pos,
										WA_Top, win_y_pos,
										WA_InnerWidth, FRM_requested_width,
										WA_InnerHeight, FRM_requested_height,
                                        WA_ScreenTitle, (ULONG)FRM_WINDOW_NAME,
                                        WA_WindowName, (ULONG)FRM_WINDOW_NAME,
	                                    WA_RMBTrap, TRUE,
	                                    WA_Activate, FALSE,
	                                    WA_CloseGadget, TRUE,
	                                    WA_DepthGadget, TRUE,
	                                    WA_DragBar, TRUE,
	                                    WA_SizeGadget, FALSE,
	                                    WA_SizeBBottom, FALSE,
                                        WA_ReportMouse, TRUE,
	                                    WA_GimmeZeroZero, TRUE, 
                                        WA_Hidden, TRUE,
										WA_IDCMP, IDCMP_RAWKEY | IDCMP_DELTAMOVE | IDCMP_MOUSEMOVE | IDCMP_MOUSEBUTTONS | IDCMP_CLOSEWINDOW,
										TAG_END); 

    if (!FRM_window) 
    {
        FRM_Console_Write("[FAILED]");
        return 0;
	}

    FRM_Console_Write("[OK]");

    // Get window signal mask.
    FRM_window_user_port = CreateMsgPort();
    FRM_window->UserPort = FRM_window_user_port;

 	FRM_window_signal = ( 1 << FRM_window->UserPort->mp_SigBit );    
    FRM_window_rastport = FRM_window->RPort;

    return 1;
}

- Main Message Loop code -


Code:
void FRM_Run_Window_32bit_Single_Buffer(void)
{
    // for FPS counter
	int fps = 0;
    LONG frames = 0;
    LONG elapsed_time = 0;
    LONG curr_time = clock();
    LONG start_time = curr_time;
    char fps_string[24];

    // Signal mask for window.
    ULONG signal_mask = ( 1 << FRM_window_user_port->mp_SigBit );

    // Enter main loop.
    BYTE FRM_main_loop = 1;

	// get bytes per row for window mode
	u_int32 bytes_per_row = FRM_requested_width * (FRM_requested_bits_per_pixel / 8);

    while (FRM_main_loop)
    {
        IO_input.mouse_dx = 0;
		IO_input.mouse_dy = 0;

        // Enter Window Message Loop - handle messages and events.
	    if(SetSignal(0L, signal_mask) & signal_mask)
	    {
		    struct IntuiMessage	*imsg;

            while( imsg = (struct IntuiMessage *)GetMsg(FRM_window_user_port) )
            {
                switch (imsg->Class)
                {
                    case IDCMP_MOUSEMOVE:
                        IO_input.mouse_dx = imsg->MouseX;
		                IO_input.mouse_dy = imsg->MouseY;
                    break;

                    case IDCMP_RAWKEY:
                        if (imsg->Code & 0x80)
                        {                
                            IO_input.keys[ (u_int8)(imsg->Code & 0x7F) ] = 0;
                        }
                        else
                        {
                            IO_input.keys[ (u_int8)(imsg->Code & 0x7F) ] = 1;
                        }
                    break;
                }
                ReplyMsg((struct Message *)imsg);
            }       
	    }  

        // -- Single Buffering routine --

                // --- DRAW HERE ---

                    // get fps
                    frames++;
                    curr_time = clock();
                    int32 TM_time_total = (curr_time - start_time) / CLOCKS_PER_SEC;

                    if (TM_time_total - elapsed_time >= 1)
                    {
                        fps = frames;

                        // reset
                        frames = 0;
                        elapsed_time += 1;
                    }

                    EN_Run(&FRM_main_loop);   

                    WritePixelArray(IO_prefs.output_buffer_32, 0, 0, bytes_per_row, FRM_window->RPort, 0, 0, FRM_requested_width, FRM_requested_height, 1 );

                    // Display FPS info.
                    memset(&fps_string, 0, 24);
                    sprintf(fps_string, "%d  %.3f", fps, IO_prefs.delta_time);

                    Move(FRM_window_rastport, 0,8);
                    Text(FRM_window_rastport, (CONST_STRPTR)fps_string, strlen(fps_string));

                // -----------------

        // -- End Single Buffering routine
    }
}

HUUUgeee thanks from advance!
mateusz_s is offline  
Old 22 March 2023, 14:38   #2
Thomas Richter
Registered User
 
Join Date: Jan 2019
Location: Germany
Posts: 3,231
Quote:
Originally Posted by mateusz_s View Post
Issue no #1
So to copy my output frame buffer to wb public window I am using:

Code:
WritePixelArray(output_buffer_32, 0, 0, bytes_per_row, FRM_window->RPort, 0, 0, output_width, output_height, output_pixel_format );
I am not sure how to make double or triple buffer. Because when using WritePixelArray(..) I am blitting to the Window Rastport.
That does not "blit" anything. It uses the CPU to copy data, on native screens even a chunky to planar conversion is involved. The problem is that the source array is either not in a mode the native Amiga graphics support, or is not on board of the graphics card to use a VGA accelerator for the conversion.


If you want to render directly to a graphics card, you need to use the P96 API in one way or another, such as allocating a bitmap on the board, then lock the bitmap, render into it, then copy it to the target. That would then use the native blitter (if there is one).


Quote:
Originally Posted by mateusz_s View Post
How can I add second or third buffer? And how can I have synced blitting using two buffers. In previurs modes I was using RethinkDisplay() for double buffering with success. I am not sure what to do in this case - I mean I got only public window without the screen.
The workbench screen has obviously only a single screen frame buffer, so there is no double buffering. If you want double buffering, you need to open a screen on your own, and use the intuition API for double buffering. There is example code in the RKRMs how to do that.




Quote:
Originally Posted by mateusz_s View Post

Issue no #2
How can I protect the cursor not to leave my window?
You don't. This is very intrusive, and very unfriendly to the user. If you want to have a "display of your own", the right abstraction is a screen, not a window.


Quote:
Originally Posted by mateusz_s View Post

I can move mouse free to move the view, but if the cursor will be outside my window,

and I press "left-button" I will lost the focus from my window and I will "back" to workbench.
That is exactly what windows are meant for, namely that users can leave them *at their own will*, and can redirect the input focus to another window if they feel like.
Thomas Richter is offline  
 


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools

Similar Threads
Thread Thread Starter Forum Replies Last Post
Problem with RTG games in PiP window. Ponki1986 support.WinUAE 32 28 May 2019 17:27
How do I open the bridgeboard rtg window on a notebook? Leandro Jardim support.WinUAE 1 15 September 2018 12:07
Automatic window resize for RTG Leffmann support.FS-UAE 2 17 May 2015 08:08
New area not refreshed after increasing RTG window size mark_k support.WinUAE 2 13 October 2013 12:40
Slow window rendering ClassicWB OS 3.5 vacum project.ClassicWB 20 14 July 2013 18:24

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT +2. The time now is 01:29.

Top

Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.
Page generated in 0.06607 seconds with 15 queries