22 March 2023, 13:01 | #1 |
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 ); 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! |
22 March 2023, 14:38 | #2 | |||
Registered User
Join Date: Jan 2019
Location: Germany
Posts: 3,231
|
Quote:
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:
Quote:
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. |
|||
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 |
|
|