I was creating a game engine, but I couldn't get to understand how thread works, I tried to look for an answer on the internet, with no answer. I had created a thread to render and the main thread is in the UI (GetMessages Windows Win32). But it doesn't show anyone that I created a sprite. (without thread I can show)
I ask that you can help me how to solve and help me understand about it.
Thanks!
WNDCLASSEX wc;
ZeroMemory(&wc, sizeof(WNDCLASSEX));
m_hinstance = GetModuleHandle(NULL);
wc.cbSize = sizeof(WNDCLASSEX);
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
wc.lpfnWndProc = WndProc;
wc.hInstance = m_hinstance;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = CreateSolidBrush(RGB(0, 0, 0));
wc.lpszClassName = L"Engine";
wc.lpszMenuName = NULL;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
if (!RegisterClassEx(&wc)) {
const wchar_t *info = L"Failed to register the window class.";
MessageBox(NULL, info, L"Error", MB_OK | MB_ICONERROR);
return false;
}
if (m_borderless == Borderless::FULLSCREEN) {
}
else if (m_borderless == Borderless::WINDOWED) {
m_hwnd = CreateWindowEx(
NULL,
wc.lpszClassName,
m_title.c_str(),
WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX,
//WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU,
0, 0,
m_size.width, m_size.height,
NULL, NULL, m_hinstance, NULL
);
if (!m_hwnd) {
const wchar_t *info = L"Failed to create window.";
MessageBox(NULL, info, L"Error", MB_OK | MB_ICONERROR);
return false;
}
RECT rect;
if (GetClientRect(m_hwnd, &rect)) {
m_border.width = m_size.width - rect.right;
m_border.height = m_size.height - rect.bottom;
SetWindowPos(m_hwnd, HWND_TOPMOST, 0, 0, m_size.width + m_border.width, m_size.height + m_border.height, SWP_NOMOVE | SWP_NOZORDER | SWP_NOACTIVATE);
}
}
else if (m_borderless == Borderless::BORDERLESS) {
int width = GetSystemMetrics(SM_CXSCREEN);
int height = GetSystemMetrics(SM_CYSCREEN);
m_hwnd = CreateWindowEx(
NULL,
wc.lpszClassName,
m_title.c_str(),
WS_POPUP | WS_THICKFRAME | WS_SYSMENU | WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_CAPTION,
0, 0,
width,
height,
NULL, NULL, m_hinstance, NULL
);
if (!m_hwnd) {
const wchar_t *info = L"Failed to create window.";
MessageBox(NULL, info, L"Error", MB_OK | MB_ICONERROR);
return false;
}
}
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
32,
0, 0, 0, 0, 0, 0,
0,
0,
0,
0, 0, 0, 0,
24,
8,
0,
PFD_MAIN_PLANE,
0,
0, 0, 0
};
int nMyPixelFormatID;
HDC hDC;
HGLRC hRC;
HGLRC hRC2;
if (!(hDC = GetDC(m_hwnd))) {
return false;
}
if (!(nMyPixelFormatID = ChoosePixelFormat(hDC, &pfd))) {
return false;
}
if (!SetPixelFormat(hDC, nMyPixelFormatID, &pfd)) {
return false;
}
if (!(hRC = wglCreateContext(hDC))) {
return false;
}
if(!(hRC2 = wglCreateContext(hDC))) {
return false;
}
if(!wglShareLists(hRC, hRC2))
{
return false;
}
if (!wglMakeCurrent(hDC, hRC)) {
return false;
}
ShowWindow(m_hwnd, SW_SHOW);
UpdateWindow(m_hwnd);
m_hdc = hDC;
m_hrc = hRC;
m_hrc2 = hRC2;
if (GLEXT::GetInstance()->Initialize()) {
LOG_SUCCESS(L"Initialize Window has been successfully.");
if (m_borderless == Borderless::FULLSCREEN) {
}
else if (m_borderless == Borderless::WINDOWED) {
glViewport(0, 0, m_size.width, m_size.height);
}
else if (m_borderless == Borderless::BORDERLESS) {
int width = GetSystemMetrics(SM_CXSCREEN);
int height = GetSystemMetrics(SM_CYSCREEN);
glViewport(0, 0, width, height);
}
m_created = true;
// vsync
SetVSync(m_vsync);
// callback
if (m_initialize_callback != NULL)
m_initialize_callback();
if (m_loadcontent_callback != NULL)
m_loadcontent_callback();
return true;
} else {
// failed load gxt
}
Main Thread:
void threadGame(bool &alive){
Engine::GLEXT::GetInstance()->Delete();
wglMakeCurrent(Window::GetInstance()->GetHDC(), Window::GetInstance()->GetHRC2());
Engine::GLEXT::GetInstance()->Initialize();
Render::GetInstance()->Initialize();
Timer time;
bool fpslimit = false;
float timer = 0.0f;
float updateTimer = time.ElapsedMillis();
float updateTick = 1000.0f / 60.0f;
UINT updates = 0;
UINT frames = 0;
float delta = 0;
float last = time.ElapsedMillis();
while(alive)
{
float now = time.ElapsedMillis();
if(fpslimit) {
if(now - updateTimer > updateTick) {
delta = now - last;
last = now;
onUpdate(delta);
updates++;
updateTimer += updateTick;
}
}
else {
delta = now - last;
last = now;
onUpdate(delta);
updates++;
}
onRender();
frames++;
if(time.Elapsed() - timer > 1.0f) {
timer += 1.0f;
// set title
std::wostringstream ws;
ws << L"Delta: ";
ws << delta;
ws << L" - FPS: ";
ws << updates;
ws << L" - Frames: ";
ws << frames;
std::wstring s(ws.str());
Window::GetInstance()->SetTitle(s);
updates = 0;
frames = 0;
}
}
}
bool alive = true;
std::thread thread(threadGame, std::ref(alive));
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
alive = false;
thread.join();