Fullscreen "Insel"

Elandril

Mitglied
Hi,

ich bastel seit letzter Woche mal wieder etwas mit OpenGL rum (Vorbereitungen für meine Bachelorarbeit) und momentan stolpere ich ein bisschen über eine triviale Angelegenheit beim Fullscreen Fenster.

Da in der Computergrafik ein Bild mehr als tausend Worte sagt, vgl. png-Anhang für das Problem.

Das Fenster wird dabei in einer Auflösung von 1280x720 bei einer Bildschirmauflösung von 1920x1080 dargestellt. Dass das rechnerisch dann durchaus so aussehen muss, ist mir relativ klar. Die Frage ist nur, wo mein Fehler liegt, damit er das Fenster typischerweise so darstellt, wie man sich das normalerweise unter "Fullscreen" vorstellt.

Hier mal die verantwortlichen Programmteile (wollte eine cpp anhängen, aber das Forum wollte nicht...)

Code:
bool closeWindow()
{
	if(window_fullscreen)
	{
		ChangeDisplaySettings(NULL, 0);
		ShowCursor(true);
	}

	if(window_render_content)
	{
		wglMakeCurrent(NULL, NULL);
		wglDeleteContext(window_render_content);

		window_render_content = NULL;
	}

	if(window_device_context)
	{
		ReleaseDC(window_handle, window_device_context);

		window_device_context = NULL;
	}

	if(window_handle)
	{
		DestroyWindow(window_handle);

		window_handle = NULL;
	}

	UnregisterClass(L"classOpenGL", hinstance);

	hinstance = NULL;

	return true;
}






bool openWindow(LPCWSTR title, int x, int y, int width, int height, int bitsPerPix, bool fullscreenflag, int multisamples)
{
	UINT ERR_MSG_MSK = MB_OK | MB_ICONERROR;
	UINT INF_MSG_MSK = MB_OK | MB_ICONINFORMATION;

	GLuint pixelformat;
	DWORD dwStyle, dwExStyle;

	hinstance = GetModuleHandle(NULL);

	RECT winrect;


	WNDCLASSEX winclass;

	// Größe der Struktur
	winclass.cbSize = sizeof(WNDCLASSEX);
	// neu zeichnen bei jeder Bewegung + eigener Device Context
	winclass.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;
	// Message Handler setzen
	winclass.lpfnWndProc = (WNDPROC) msgHandle;
	// Kein Speicher für extra Fensterdaten
	winclass.cbClsExtra = 0;
	winclass.cbWndExtra = 0;
	// Instanz setzen
	winclass.hInstance = hinstance;
	// Icon für das Fenster
	winclass.hIcon = LoadIcon(NULL, IDI_WINLOGO);
	// Cursor Set
	winclass.hCursor = LoadCursor(NULL, IDC_ARROW);
	// Für OpenGL kein Background
	winclass.hbrBackground = NULL;
	// Kein Menü
	winclass.lpszMenuName = NULL;
	// Fensterklassenname
	winclass.lpszClassName = L"classOpenGL";
	winclass.hIconSm = NULL;

	// Klasse registrieren
	if(!RegisterClassEx(&winclass))
	{
		MessageBox(NULL, L"Fehler beim Registrieren der Fensterklasse", L"Fehler", ERR_MSG_MSK);

		return false;
	}


	window_fullscreen = fullscreenflag;
	
	if(window_fullscreen)
	{
		// Device Mode
		DEVMODE devmode;

		// Struktur löschen
		memset(&devmode, 0, sizeof(devmode));

		// Größe der Struktur
		devmode.dmSize = sizeof(devmode);
		// Width / Height
		devmode.dmPelsWidth = width;
		devmode.dmPelsHeight = height;
		// Bits pro Pixel
		devmode.dmBitsPerPel = bitsPerPix;
		devmode.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;


		if(ChangeDisplaySettings(&devmode, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
		{
			MessageBox(NULL, L"Angeforderter Fullscreen Modus nicht unterstützt", L"Fehler", INF_MSG_MSK);

			window_fullscreen = false;
		}
	}


	if(window_fullscreen)
	{
		dwExStyle = WS_EX_APPWINDOW;
		dwStyle = WS_POPUP;
	}
	else
	{
		dwExStyle = WS_EX_APPWINDOW;
		dwStyle = WS_OVERLAPPEDWINDOW;
	}


	winrect.left = x;
	winrect.top = y;
	winrect.right = width;
	winrect.bottom = height;

	AdjustWindowRectEx(&winrect, dwStyle, false, dwExStyle);

	if(!(window_handle = CreateWindowEx(dwExStyle, L"classOpenGL", title, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dwStyle, winrect.left, winrect.top, winrect.right, winrect.bottom, NULL, NULL, hinstance, NULL)))
	{
		closeWindow();
		MessageBox(NULL, L"Fehler beim Erzeugen des Fensters!", L"Fehler", ERR_MSG_MSK);
		return false;
	}


	static PIXELFORMATDESCRIPTOR pfd = 
	{
		// Größe der Struktur
		sizeof(PIXELFORMATDESCRIPTOR),
		// Version
		1,
		// Flags
		PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
		// RGBA-Format
		PFD_TYPE_RGBA,
		// Bits pro Pixel
		bitsPerPix,
		// Farb-Bits/Shifts
		0, 0, 0, 0, 0, 0,
		// Alpha-Buffer
		0, 
		// shift-bit
		0,
		// accumulation buffer
		0,
		// ignoriere accumulatoin bits
		0, 0, 0, 0,
		// Z-Buffer Tiefe
		24,
		// Stencil Buffer Tiefe
		8,
		// kein Auxiliary Buffer
		0,
		// Hauptzeichenlayer
		PFD_MAIN_PLANE,
		// reserviert
		0,
		// Layer Maske
		0, 0, 0
	};


	if(!(window_device_context = GetDC(window_handle)))
	{
		closeWindow();

		MessageBox(NULL, L"Device Context konnte nicht erstellt werden!", L"Fehler", ERR_MSG_MSK);

		return false;
	}


	if(!(pixelformat = ChoosePixelFormat(window_device_context, &pfd)))
	{
		closeWindow();

		MessageBox(NULL, L"Kein Pixelformat gefunden!", L"Fehler", ERR_MSG_MSK);

		return false;
	}


	if(!SetPixelFormat(window_device_context, pixelformat, &pfd))
	{
		closeWindow();

		MessageBox(NULL, L"Setzen des Pixelformats fehlgeschlagen", L"Fehler", ERR_MSG_MSK);

		return false;
	}


	if(!(window_render_content = wglCreateContext(window_device_context)))
	{
		closeWindow();

		MessageBox(NULL, L"Ein Rendering Content konnte nicht erzeugt werden", L"Fehler", ERR_MSG_MSK);

		return false;
	}


	if(!wglMakeCurrent(window_device_context, window_render_content))
	{
		closeWindow();

		MessageBox(NULL, L"OpenGL Rendering Content konnte nicht aktiviert werden", L"Fehler", ERR_MSG_MSK);

		return false;
	}




	// Multisample RC
	if(multisamples > 0)
	{
		PFNWGLCHOOSEPIXELFORMATARBPROC wglChoosePixelFormatARB = (PFNWGLCHOOSEPIXELFORMATARBPROC) wglGetProcAddress("wglChoosePixelFormatARB");

		if(!wglChoosePixelFormatARB)
		{
			closeWindow();

			MessageBox(NULL, L"wglChoosePixelFormatARB(...) nicht vorhanden", L"Extension Fehler", ERR_MSG_MSK);

			return false;
		}


		int attributes[] = 
		{
			WGL_DRAW_TO_WINDOW_ARB, GL_TRUE,
			WGL_SUPPORT_OPENGL_ARB, GL_TRUE,
			WGL_DOUBLE_BUFFER_ARB, GL_TRUE,
			WGL_PIXEL_TYPE_ARB, WGL_TYPE_RGBA_ARB,
			WGL_COLOR_BITS_ARB, bitsPerPix,
			WGL_DEPTH_BITS_ARB, 24,
			WGL_STENCIL_BITS_ARB, 8,
			WGL_SAMPLE_BUFFERS_ARB, 1,
			WGL_SAMPLES_ARB, multisamples,
			0
		};

		int proper_pixelformat;
		UINT numFormats;

		// Fenster kaputt machen und neu bauen
		closeWindow();

		// Klasse registrieren
		if(!RegisterClassEx(&winclass))
		{
			MessageBox(NULL, L"Fehler beim Registrieren der Fensterklasse", L"Fehler", ERR_MSG_MSK);

			return false;
		}
		if(!(window_handle = CreateWindowEx(dwExStyle, L"classOpenGL", title, WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dwStyle, winrect.left, winrect.top, winrect.right, winrect.bottom, NULL, NULL, hinstance, NULL)))
		{
			DWORD err = GetLastError();

			closeWindow();
			MessageBox(NULL, L"Fehler beim Erzeugen des Fensters!", L"Fehler", ERR_MSG_MSK);
			return false;
		}

		if(!(window_device_context = GetDC(window_handle)))
		{
			closeWindow();

			MessageBox(NULL, L"Fehler beim erzeugen des neuen Device Context", L"Device Context Fehler", ERR_MSG_MSK);

			return false;
		}


		if(!wglChoosePixelFormatARB(window_device_context, attributes, NULL, 1, &proper_pixelformat, &numFormats))
		{
			closeWindow();

			MessageBox(NULL, L"wglChoosePixelFormatARB(...) konnte kein passendes Pixelformat finden", L"Pixelformat Fehler", ERR_MSG_MSK);

			return false;
		}


		if(!SetPixelFormat(window_device_context, proper_pixelformat, &pfd))
		{
			DWORD err = GetLastError();

			closeWindow();

			MessageBox(NULL, L"Setzen des eigentlichen Pixelformats nicht möglich", L"Pixelformat Fehler", ERR_MSG_MSK);

			return false;
		}

		if(!(window_render_content = wglCreateContext(window_device_context)))
		{
			closeWindow();

			MessageBox(NULL, L"Der neue Rendering Content konnte nicht erzeugt werden", L"Fehler", ERR_MSG_MSK);

			return false;
		}


		if(!wglMakeCurrent(window_device_context, window_render_content))
		{
			closeWindow();

			MessageBox(NULL, L"Neuer Context und Content konnten nicht gebunden werden", L"Fehler", ERR_MSG_MSK);

			return false;
		}
	}



	ShowWindow(window_handle, SW_SHOW);
	SetForegroundWindow(window_handle);
	SetFocus(window_handle);

	if(window_fullscreen)
		resizeWindow(width, height);

	return true;
}





int WINAPI  WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
	//openWindow(L"Natives Window für OpenGL", 250, 150, 1280, 720, 32, false, 8);
	openWindow(L"Natives Window für OpenGL", 250, 150, 1280, 720, 32, true, 8);

	init();

	MSG msg;

	bool done = false;

	while(!done)
	{
		if(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
		{
			if(msg.message == WM_QUIT)
				done = true;

			else
			{
				TranslateMessage(&msg);
				DispatchMessage(&msg);
			}
		}
		else
		{
			update();
			render();
		}
	}


	kill();

	closeWindow();

	return 0;
}

vielleicht ist ja jemand schon mal über diesen Fehler gestolpert oder hat sonst irgendwie eine Idee.

Danke soweit mal!
 

Anhänge

  • Fullscreen.png
    Fullscreen.png
    237,3 KB · Aufrufe: 28
Moin,

verstehe Deine Frage nicht wirklich ...
Möchtest Du wissen, warum der Rahmen fehlt oder warum das Bild nicht größer ist, als es nun mal ist ?

Gruß
Klaus
 
Hallo Klaus,

danke für deine Antwort.

Mein Problem ist, dass das Fenster eben, trotz fullscreen_flag mehr oder weniger als Fenster ohne Rahmen angezeigt wird mit einer Auflösung von den spezifizierten 1280x720. Wenn ich statt dieser Auflösung eine Auflösung von 1920x1080 übergebe, dann wird das Fenster auch korrekt im Vollbild-Modus angezeigt. Die Frage ist also jetzt, was ich falsch mache, dass nur diese "Fenster-Insel" dargestellt wird und nicht auch bei einer übergebenen Auflösung von 1280x720 das Fenster bildschirmfüllend dargestellt wird.
 
Nach einiger Recherche habe ich den starken Verdacht, dass der Display unmittelbar nach dem Setzen via DEVMODE einfach wieder auf die Desktop-Auflösung zurück gesetzt wird. Ist nur eine Vermutung, aber hat jemand eine Idee, wie man das unterbinden kann?
 
Fehler gefunden.

Nachdem das alte Fenster zwecks Multisample-Context zerstört wird, wurden die Fullscreen-Settings zurück gesetzt -> entsprechend kam das Fenster zustande...
 

Neue Beiträge

Zurück