Jump to content

C++ Migrating 2.16 -> 2.17 Help plz..


photo

Recommended Posts

Hello.

We are migrating from version 2.16 to version 2.17.

 

Here's a great sample.

 

The 2.17 build is a success.
But I get a debugging error...

Is there anything else that needs to be written during engine init?
I need help.

 

 

source.zip

Link to comment

Hello.

Your integration have the wrong mix of using engine windows and external windows. This is what leads to errors.

Engine windows are wholly owned by the engine's window manager. In this case, only the engine tells the system proxy what to do with the windows.

For external windows the engine registers only the resources needed for rendering. It then communicates through the proxy when the user can render.

When integrating into another framework, I would recommend using only external windows so that you have full control over them. To do this, you need to tell the engine that you don't need to create engine windows from the start. We use -main_window 0 for this. Then you need to remove the automatic closing of the windowless engine: -auto_quit 0. You can also make the engine always updated: -background_update 1.

Unigine::Vector<char *> argv;
argv.append("-main_window");
argv.append("0");
argv.append("-auto_quit");
argv.append("0");
argv.append("-background_update");
argv.append("1");

Unigine::EnginePtr engine(init_params, argv.size(), argv.get());

Next, in the system proxy, in the createWindow and RemoveWindow methods, we will delete all the logic. We will also add an engine stop if someone calls these methods, since these functions are only used for engine windows.

WIN_HANDLE CustomWinAPIProxy::createWindow(int width, int height)
{
	Log::fatal("CustomWinAPIProxy::createWindow(): don't use engine windows\n");
	return WIN_HANDLE();
}

void CustomWinAPIProxy::removeWindow(WIN_HANDLE win_handle)
{
	Log::fatal("CustomWinAPIProxy::removeWindow(): don't use engine windows\n");
}

Now we need to create an external render window. To do this, we inherit Window from ExternalWindow. In the constructor, we add the setting of the window handler and the window procedure.

Window::Window(/*...*/)
{
	std::basic_string<TCHAR> ClassName1 = "MyWndClass";
	m_hWnd = CreateWindow(ClassName1.c_str(), WindowName.c_str(), WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, nullptr, nullptr, hInstance, pData);
	win_handle_.hwnd = m_hWnd;
	SetWindowLongPtr(m_hWnd, GWLP_WNDPROC, (LONG_PTR)WndProc);
}

Next, we need to register this window in the engine using registerExternalWindow. For example, let's do this in the StartEngineLoop:

void SampleApp::StartEngineLoop()
{
	engine_ = Engine::get();
	static_cast<CustomWinAPIProxy *>(CustomSystemProxy::get())->registerExternalWindow(m_pMainWindow, m_pMainWindow->getWinHandle(), Math::ivec2(1600, 900));
	ShowWindow(m_pMainWindow->GetHwnd(), SW_SHOW);
}

We also need to resize this rendering window. Therefore, we add WM_SIZE processing to WndProc:

case WM_SIZE:
	if (CustomSystemProxy::get())
	{
		UINT width = LOWORD(lParam);
		UINT height = HIWORD(lParam);
		WIN_HANDLE h;
		h.hwnd = hWnd;
		CustomSystemProxy::get()->resizeExternalWindowBuffers(h, Math::ivec2(width, height));
	}
	break;
}

And the last step in the render method is to change the viewport to the current window size:

RECT rect;
GetClientRect(static_cast<HWND>(handle.hwnd), &rect);
RenderState::setViewport(0, 0, rect.right - rect.left, rect.bottom - rect.top);
viewport->renderEngine(camera);

We can also receive input events from this window and send them to the engine. And if you need engine windows in the future, you can implement the logic for the createWindow and RemoveWindow functions, as well as all other window-related functions.

image.png

  • Like 1
Link to comment
×
×
  • Create New...