Multisampling -> com_error

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Mabuntu
Beiträge: 3
Registriert: 10.08.2010, 20:22
Echter Name: Matej Kostalek

Multisampling -> com_error

Beitrag von Mabuntu »

Hallo zusammen.

Nun ich habe mich mal wieder in die Welt von C++ und D3D gewagt und mir das neue DXSDK installiert. Mein Ziel ist ein kleines und einfaches Rennspiel für mich. Nun habe ich mit den Basics begonnen und versucht, es so einfach wie möglich zu halten. Mein erstes Ziel ist ein Fenster, in dem ich verschiedene Auflösungen setzen sowie Multisampling ein/ausschalten kann.

Hier mein Code:

Code: Alles auswählen

#include "Core.h"

HINSTANCE               g_hInstance = NULL;
HWND                    g_hWnd = NULL;

bool                    g_bKeys[256] = { false };
bool                    g_bToggleKeys[256] = { false };

IDXGIFactory1          *g_pFactory = NULL;
IDXGIAdapter1          *g_pAdapter = NULL;
IDXGIOutput            *g_pOutput = NULL;
ID3D11Device           *g_pDevice = NULL;
ID3D11DeviceContext    *g_pContext = NULL;

UINT                    g_numModes = 0;
DXGI_MODE_DESC         *g_pModeList = NULL;
DXGI_MODE_DESC          g_fullscreenModes[3] = ZERO_ARRAY;
DXGI_MODE_DESC          g_windowedMode = ZERO_ARRAY;

IDXGISwapChain         *g_pSwapChain = NULL;
ID3D11RenderTargetView *g_pRenderTargetView = NULL;
ID3D11Texture2D        *g_pDepthStencil = NULL;
ID3D11DepthStencilView *g_pDepthStencilView = NULL;
bool                    g_bViewsCreated = false;

//-----------------------------------------------------------------------------
// wWinMain()
// Der Haupteinstiegspunkt der Anwendung.
//-----------------------------------------------------------------------------
int WINAPI wWinMain( HINSTANCE hInstance, 
	                 HINSTANCE hPrevInstance, 
					 LPWSTR pCmdLine, 
					 int showCmd )
{
	g_hInstance = hInstance;

	bool bFullscreen = wcscmp( pCmdLine, L"fullscreen" ) ? false : true;

	HRESULT hr = InitWindow( L"D3D11 Tutorial", 640, 480 );

	if( SUCCEEDED( hr ) )
		hr = InitDevice( D3D_FEATURE_LEVEL_10_0 );

	if( SUCCEEDED( hr ) )
		hr = EnumDisplayModes( DXGI_FORMAT_R8G8B8A8_UNORM_SRGB );

	if( SUCCEEDED( hr ) )
		hr = FindDisplayMode( 800, 600, 60, g_fullscreenModes[0] );

	if( SUCCEEDED( hr ) )
		hr = FindDisplayMode( 1280, 800, 60, g_fullscreenModes[1] );

	if( SUCCEEDED( hr ) )
		hr = FindDisplayMode( 1920, 1080, 60, g_fullscreenModes[2] );

	if( SUCCEEDED( hr ) )
		hr = SetRenderTarget( 1 );

	if( SUCCEEDED( hr ) && bFullscreen )
		hr = SetFullscreenMode( g_fullscreenModes[0] );

	if( SUCCEEDED( hr ) )
		hr = MessageLoop();

	Cleanup();

	if( FAILED( hr ) )
	{
		MessageBox(
			NULL,
			DXGetErrorDescription( hr ),
			L"D3D11 Tutorial Error",
			MB_ICONERROR | MB_SETFOREGROUND );
	}

	return 0;
}



//-----------------------------------------------------------------------------
// IsKeyDown()
// Prüft einen Tastenstatus.
//-----------------------------------------------------------------------------
bool IsKeyDown( UINT key )
{
	if( key > 255 )
		return false;

	if( g_bKeys[key] )
		return true;

	return false;
}



//-----------------------------------------------------------------------------
// IsToggleKeyDown()
// Prüft einen einmaligen Tastenstatus.
//-----------------------------------------------------------------------------
bool IsToggleKeyDown( UINT key )
{
	if( key > 255 )
		return false;

	if( g_bKeys[key] )
	{
		if( !g_bToggleKeys[key] )
		{
			g_bToggleKeys[key] = true;
			return true;
		}
	}

	return false;
}



//-----------------------------------------------------------------------------
// IsFullscreenMode()
// Prüft, ob sich das Swapchain im Vollbildmodus befindet.
//-----------------------------------------------------------------------------
bool IsFullscreenMode( void )
{
	if( NULL == g_pSwapChain )
		return false;

	BOOL bFullscreen = FALSE;
	g_pSwapChain->GetFullscreenState( &bFullscreen, NULL );

	if( bFullscreen )
		return true;

	return false;
}



//-----------------------------------------------------------------------------
// WndProc()
// Verarbeitet die Fensternachrichten.
//-----------------------------------------------------------------------------
LRESULT CALLBACK WndProc( HWND hWnd,
	                      UINT msg,
						  WPARAM wParam,
						  LPARAM lParam )
{
	switch( msg )
	{
	case WM_DESTROY:
		PostQuitMessage( 0 );
		return 0;

	case WM_KEYDOWN:
		g_bKeys[wParam] = true;
		break;

	case WM_KEYUP:
		g_bKeys[wParam] = false;
		g_bToggleKeys[wParam] = false;
		break;
	}

	LRESULT result = DefWindowProc(
		hWnd, 
		msg,
		wParam,
		lParam );

	return result;
}



//-----------------------------------------------------------------------------
// InitWindow()
// Erstellt das Fenster.
//-----------------------------------------------------------------------------
HRESULT InitWindow( LPCWSTR pTitle, UINT width, UINT height )
{
	HBRUSH hColor = 
		reinterpret_cast<HBRUSH>( GetStockObject( BLACK_BRUSH ) );
	
	WNDCLASSEX wcex = ZERO_ARRAY;

	wcex.cbClsExtra    = 0;
	wcex.cbSize        = sizeof( WNDCLASSEX );
	wcex.cbWndExtra    = 0;
	wcex.hbrBackground = hColor;
	wcex.hCursor       = LoadCursor( NULL, IDC_ARROW );
	wcex.hIcon         = LoadIcon( NULL, IDI_APPLICATION );
	wcex.hIconSm       = LoadIcon( NULL, IDI_APPLICATION );
	wcex.hInstance     = g_hInstance;
	wcex.lpfnWndProc   = WndProc;
	wcex.lpszClassName = L"WindowClass";
	wcex.lpszMenuName  = NULL;
	wcex.style         = CS_DBLCLKS;

	if( !RegisterClassEx( &wcex ) )
		return E_FAIL;

	int screenX = GetSystemMetrics( SM_CXSCREEN );
	int screenY = GetSystemMetrics( SM_CYSCREEN );

	RECT rect = { 0, 0, width, height };
	DWORD style = WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU;
	
	AdjustWindowRect( &rect, style, FALSE );

	int w = static_cast<int>( rect.right - rect.left );	
	int h = static_cast<int>( rect.bottom - rect.top );
	int x = static_cast<int>( ( screenX - w ) / 2 );	
	int y = static_cast<int>( ( screenY - h ) / 2 );

	g_hWnd = CreateWindow(
		L"WindowClass",
		pTitle,
		style,
		x,
		y,
		w,
		h,
		NULL,
		NULL,
		g_hInstance,
		NULL );

	if( NULL == g_hWnd )
		return E_FAIL;

	ShowWindow( g_hWnd, SW_SHOWNORMAL );
	UpdateWindow( g_hWnd );
	SetForegroundWindow( g_hWnd );

	return S_OK;
}



//-----------------------------------------------------------------------------
// InitDevice()
// Erstellt das Renderdevice.
//-----------------------------------------------------------------------------
HRESULT InitDevice( D3D_FEATURE_LEVEL level )
{
	HRESULT hr = CreateDXGIFactory1(
		__uuidof( IDXGIFactory1 ),
		reinterpret_cast<void**>( &g_pFactory ) );

	if( FAILED( hr ) )
		return hr;

	hr = g_pFactory->EnumAdapters1( 0, &g_pAdapter );

	if( FAILED( hr ) )
		return hr;

	hr = g_pAdapter->EnumOutputs( 0, &g_pOutput );

	if( FAILED( hr ) )
		return hr;

	D3D_FEATURE_LEVEL caps = D3D_FEATURE_LEVEL_9_1;

	hr = D3D11CreateDevice(
		g_pAdapter,
		D3D_DRIVER_TYPE_UNKNOWN,
		NULL,
		0,
		NULL,
		0,
		D3D11_SDK_VERSION,
		&g_pDevice,
		&caps,
		&g_pContext );

	if( FAILED( hr ) )
		return hr;

	if( caps < level )
		return E_FAIL;

	return S_OK;
}



//-----------------------------------------------------------------------------
// EnumDisplayModes()
// Speichert alle gültigen Displaymodi.
//-----------------------------------------------------------------------------
HRESULT EnumDisplayModes( DXGI_FORMAT format )
{
	HRESULT hr = g_pOutput->GetDisplayModeList(
		format,
		0,
		&g_numModes,
		NULL );

	if( FAILED( hr ) )
		return hr;

	if( 0 == g_numModes )
		return E_FAIL;

	g_pModeList = new DXGI_MODE_DESC[g_numModes];

	if( NULL == g_pModeList )
		return E_OUTOFMEMORY;

	hr = g_pOutput->GetDisplayModeList(
		format,
		0,
		&g_numModes,
		g_pModeList );

	if( FAILED( hr ) )
		return hr;

	return S_OK;
}



//-----------------------------------------------------------------------------
// FindDisplayMode()
// Sucht nach einem gültigen Displaymodus.
//-----------------------------------------------------------------------------
HRESULT FindDisplayMode( UINT width, 
	                     UINT height,
						 UINT refreshRate,
						 DXGI_MODE_DESC &validMode )
{
	UINT index = 0;
	bool bFound = false;

	for( UINT n = 0; n < g_numModes; ++n )
	{
		if( refreshRate == static_cast<UINT>( 
			g_pModeList[n].RefreshRate.Numerator /
			g_pModeList[n].RefreshRate.Denominator ) )
		{
			if( g_pModeList[n].Width <= width &&
				g_pModeList[n].Height <= height )
			{
				index = n;
				bFound = true;
			}
		}
	}

	if( !bFound )
		return E_FAIL;

	memcpy_s(
		&validMode,
		sizeof( DXGI_MODE_DESC ),
		&g_pModeList[index],
		sizeof( DXGI_MODE_DESC ) );

	return S_OK;
}



//-----------------------------------------------------------------------------
// InitSwapChain()
// Erstellt das Swapchain.
//-----------------------------------------------------------------------------
HRESULT InitSwapChain( UINT sampleCount )
{
	RECT rect = ZERO_ARRAY;
	GetClientRect( g_hWnd, &rect );

	DXGI_FORMAT format = g_pModeList[0].Format;

	UINT width = static_cast<UINT>( rect.right );
	UINT height = static_cast<UINT>( rect.bottom );

	DXGI_MODE_SCALING scaling = DXGI_MODE_SCALING_UNSPECIFIED;
	DXGI_MODE_SCANLINE_ORDER order = DXGI_MODE_SCANLINE_ORDER_UNSPECIFIED;

	DXGI_SWAP_CHAIN_DESC desc = ZERO_ARRAY;

	desc.BufferDesc.Format                  = format;
	desc.BufferDesc.Width                   = width;
	desc.BufferDesc.Height                  = height;
	desc.BufferDesc.Scaling                 = scaling;
	desc.BufferDesc.ScanlineOrdering        = order;
	desc.BufferDesc.RefreshRate.Numerator   = 0;
	desc.BufferDesc.RefreshRate.Denominator = 0;

	desc.BufferCount        = 1;
	desc.BufferUsage        = DXGI_USAGE_RENDER_TARGET_OUTPUT;
	desc.Flags              = DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH;
	desc.OutputWindow       = g_hWnd;
	desc.SampleDesc.Count   = sampleCount;
	desc.SampleDesc.Quality = 0;
	desc.SwapEffect         = DXGI_SWAP_EFFECT_DISCARD;
	desc.Windowed           = TRUE;

	HRESULT hr = g_pFactory->CreateSwapChain(
		g_pDevice,
		&desc,
		&g_pSwapChain );

	if( FAILED( hr ) )
		return hr;

	g_pFactory->MakeWindowAssociation( g_hWnd, DXGI_MWA_NO_ALT_ENTER );

	memcpy_s(
		&g_windowedMode,
		sizeof( DXGI_MODE_DESC ),
		&desc.BufferDesc,
		sizeof( DXGI_MODE_DESC ) );

	return S_OK;
}



//-----------------------------------------------------------------------------
// SetRenderTarget()
// Konfiguriert den Renderbereich.
//-----------------------------------------------------------------------------
HRESULT SetRenderTarget( UINT sampleCount )
{
	HRESULT hr = S_OK;
	DXGI_SWAP_CHAIN_DESC desc = ZERO_ARRAY;
	bool bFullscreen = false;

	if( g_pSwapChain )
	{
		g_pSwapChain->GetDesc( &desc );

		if( desc.SampleDesc.Count == sampleCount )
			return S_OK;

		bFullscreen = IsFullscreenMode();

		if( bFullscreen )
		{
			hr = SetWindowedMode( g_windowedMode );

			if( FAILED( hr ) )
				return hr;
		}

		ReleaseViews();
		SafeReleaseCom( g_pSwapChain );
	}

	hr = InitSwapChain( sampleCount );

	if( FAILED( hr ) )
		return hr;

	// Vor dem Wechsel zurück in den Vollbildmodus dem Fenstermodus ein
	// wenig Zeit geben. Somit ist sichergestellt, das dieser korrekt
	// übernommen worden ist.
	if( bFullscreen )
	{
		Sleep( 50 );
		hr = SetFullscreenMode( desc.BufferDesc );

		if( FAILED( hr ) )
			return hr;
	}

	return S_OK;
}



//-----------------------------------------------------------------------------
// SetWindowedMode()
// Setzt den Fenstermodus.
//-----------------------------------------------------------------------------
HRESULT SetWindowedMode( const DXGI_MODE_DESC &newMode )
{
	HRESULT hr = S_OK;

	BOOL bFullscreen = FALSE;
	g_pSwapChain->GetFullscreenState( &bFullscreen, NULL );

	if( bFullscreen )
	{
		hr = g_pSwapChain->SetFullscreenState( FALSE, NULL );

		if( FAILED( hr ) )
			return hr;

		hr = ResizeBuffers();

		if( FAILED( hr ) )
			return hr;
	}

	hr = ResizeTarget( newMode );

	if( FAILED( hr ) )
		return hr;

	return S_OK;
}



//-----------------------------------------------------------------------------
// SetFullscreenMode()
// Setzt den Vollbildmodus.
//-----------------------------------------------------------------------------
HRESULT SetFullscreenMode( const DXGI_MODE_DESC &newMode )
{
	HRESULT hr = S_OK;

	BOOL bFullscreen = FALSE;
	g_pSwapChain->GetFullscreenState( &bFullscreen, NULL );

	if( !bFullscreen )
	{
		DXGI_SWAP_CHAIN_DESC desc = ZERO_ARRAY;
		g_pSwapChain->GetDesc( &desc );

		memcpy_s(
			&g_windowedMode,
			sizeof( DXGI_MODE_DESC ),
			&desc.BufferDesc,
			sizeof( DXGI_MODE_DESC ) );

		hr = ResizeTarget( newMode );

		if( FAILED( hr ) )
			return hr;

		hr = g_pSwapChain->SetFullscreenState( TRUE, NULL );

		if( FAILED( hr ) )
			return hr;

		hr = ResizeBuffers();

		if( FAILED( hr ) )
			return hr;
	}

	hr = ResizeTarget( newMode );

	if( FAILED( hr ) )
		return hr;

	return S_OK;
}



//-----------------------------------------------------------------------------
// ResizeBuffers()
// Passt das Swapchain der neuen Fensterklientgrösse an.
//-----------------------------------------------------------------------------
HRESULT ResizeBuffers( void )
{
	ReleaseViews();

	RECT rect = ZERO_ARRAY;
	GetClientRect( g_hWnd, &rect );

	DXGI_SWAP_CHAIN_DESC desc = ZERO_ARRAY;
	g_pSwapChain->GetDesc( &desc );

	HRESULT hr = g_pSwapChain->ResizeBuffers(
		desc.BufferCount,
		static_cast<UINT>( rect.right ),
		static_cast<UINT>( rect.bottom ),
		desc.BufferDesc.Format,
		DXGI_SWAP_CHAIN_FLAG_ALLOW_MODE_SWITCH );

	if( FAILED( hr ) )
		return hr;

	return S_OK;
}



//-----------------------------------------------------------------------------
// ResizeTarget()
// Aktualisiert den Renderbereich.
//-----------------------------------------------------------------------------
HRESULT ResizeTarget( const DXGI_MODE_DESC &newMode )
{
	DXGI_SWAP_CHAIN_DESC desc = ZERO_ARRAY;
	DXGI_MODE_DESC mode = ZERO_ARRAY;

	g_pSwapChain->GetDesc( &desc );

	memcpy_s(
		&mode,
		sizeof( DXGI_MODE_DESC ),
		&desc.BufferDesc,
		sizeof( DXGI_MODE_DESC ) );

	if( mode.Width                   != newMode.Width ||
		mode.Height                  != newMode.Height ||
		mode.Format                  != newMode.Format ||
		mode.Scaling                 != newMode.Scaling ||
		mode.ScanlineOrdering        != newMode.ScanlineOrdering ||
		mode.RefreshRate.Numerator   != newMode.RefreshRate.Numerator ||
		mode.RefreshRate.Denominator != newMode.RefreshRate.Denominator )
	{
		HRESULT hr = g_pSwapChain->ResizeTarget( &newMode );

		if( FAILED( hr ) )
			return hr;

		hr = ResizeBuffers();

		if( FAILED( hr ) )
			return hr;
	}

	return S_OK;
}



//-----------------------------------------------------------------------------
// MessageLoop()
// Erstellt die Swapchain Ressourcen.
//-----------------------------------------------------------------------------
HRESULT CreateViews( void )
{
	DXGI_SWAP_CHAIN_DESC desc = ZERO_ARRAY;
	g_pSwapChain->GetDesc( &desc );

	UINT width = desc.BufferDesc.Width;
	UINT height = desc.BufferDesc.Height;

	HRESULT hr = CreateRenderTargetView();

	if( FAILED( hr ) )
		return hr;

	hr = CreateDepthStencilView( width, height, desc.SampleDesc.Count );

	if( FAILED( hr ) )
		return hr;

	g_pContext->OMSetRenderTargets(
		1, 
		&g_pRenderTargetView, 
		g_pDepthStencilView );

	D3D11_VIEWPORT vp = ZERO_ARRAY;

	vp.Width    = static_cast<FLOAT>( width );
	vp.Height   = static_cast<FLOAT>( height );
	vp.MinDepth = 0.0f;
   	vp.MaxDepth = 1.0f;
	vp.TopLeftX = 0;
	vp.TopLeftY = 0;

	g_pContext->RSSetViewports( 1, &vp );
	g_bViewsCreated = true;

	return S_OK;
}



//-----------------------------------------------------------------------------
// CreateRenderTargetView()
// Erstellt die Rendertarget Textur.
//-----------------------------------------------------------------------------
HRESULT CreateRenderTargetView( void )
{
	ID3D11Texture2D *pRenderTarget = NULL;

	HRESULT hr = g_pSwapChain->GetBuffer(
		0,
		__uuidof( ID3D11Texture2D ),
		reinterpret_cast<void**>( &pRenderTarget ) );

	if( FAILED( hr ) )
		return hr;

	hr = g_pDevice->CreateRenderTargetView(
		pRenderTarget, 
		NULL, 
		&g_pRenderTargetView );

	SafeReleaseCom( pRenderTarget );

	if( FAILED( hr ) )
		return hr;

	return S_OK;
}



//-----------------------------------------------------------------------------
// CreateDepthStencilView()
// Erstellt die Depthstencil Textur.
//-----------------------------------------------------------------------------
HRESULT CreateDepthStencilView( UINT width, UINT height, UINT sampleCount )
{
	D3D11_TEXTURE2D_DESC desc = ZERO_ARRAY;

    desc.Width              = width;
    desc.Height             = height;
    desc.MipLevels          = 1;
    desc.ArraySize          = 1;
    desc.Format             = DXGI_FORMAT_D24_UNORM_S8_UINT;
    desc.SampleDesc.Count   = sampleCount;
    desc.SampleDesc.Quality = 0;
    desc.Usage              = D3D11_USAGE_DEFAULT;
    desc.BindFlags          = D3D11_BIND_DEPTH_STENCIL;
    desc.CPUAccessFlags     = 0;
    desc.MiscFlags          = 0;
    
	HRESULT hr = g_pDevice->CreateTexture2D(
		&desc, 
		NULL, 
		&g_pDepthStencil );

    if( FAILED( hr ) )
        return hr;

	D3D11_DSV_DIMENSION dimension = ( sampleCount > 1 ) ?
		D3D11_DSV_DIMENSION_TEXTURE2DMS :
		D3D11_DSV_DIMENSION_TEXTURE2D;

    D3D11_DEPTH_STENCIL_VIEW_DESC dsv;
	ZeroMemory( &dsv, sizeof( D3D11_DEPTH_STENCIL_VIEW_DESC ) );

    dsv.Format             = desc.Format;
    dsv.Flags              = 0;
	dsv.Texture2D.MipSlice = 0;
	dsv.ViewDimension      = dimension;

    hr = g_pDevice->CreateDepthStencilView( 
		g_pDepthStencil, 
		&dsv,
		&g_pDepthStencilView );
    
	if( FAILED( hr ) )
		return hr;

	return S_OK;
}



//-----------------------------------------------------------------------------
// MessageLoop()
// Startet die Nachrichtenschleife.
//-----------------------------------------------------------------------------
HRESULT MessageLoop( void )
{	
	HRESULT hr = S_OK;
	MSG msg = ZERO_ARRAY;

	while( WM_QUIT != msg.message )
	{
		if( PeekMessage( &msg, NULL, 0, 0, PM_REMOVE ) )
		{
			TranslateMessage( &msg );
			DispatchMessage( &msg );
		}
		else
		{
			hr = Update();

			if( SUCCEEDED( hr ) )
				hr = Render();

			if( FAILED( hr ) )
				SendMessage( g_hWnd, WM_CLOSE, 0, 0 );
		}
	}

	return hr;
}



//-----------------------------------------------------------------------------
// CheckForBufferMatch()
// Prüft, ob der Fensterklient und die Swapchainbuffer übereinstimmen.
//-----------------------------------------------------------------------------
HRESULT CheckForBufferMatch( void )
{
	RECT rect = ZERO_ARRAY;
	GetClientRect( g_hWnd, &rect );

	DXGI_SWAP_CHAIN_DESC desc = ZERO_ARRAY;
	g_pSwapChain->GetDesc( &desc );

	if( static_cast<UINT>( rect.right ) != desc.BufferDesc.Width ||
		static_cast<UINT>( rect.bottom ) != desc.BufferDesc.Height )
	{
		HRESULT hr = ResizeBuffers();

		if( FAILED( hr ) )
			return hr;
	}

	return S_OK;
}



//-----------------------------------------------------------------------------
// Update()
// Aktualisiert die Umgebung.
//-----------------------------------------------------------------------------
HRESULT Update( void )
{	
	if( IsToggleKeyDown( VK_ESCAPE ) )
	{
		SendMessage( g_hWnd, WM_CLOSE, 0, 0 );
		return S_OK;
	}

	HRESULT hr = S_OK;

	if( IsToggleKeyDown( VK_NUMPAD0 ) )
		hr = SetWindowedMode( g_windowedMode );
	else if( IsToggleKeyDown( VK_NUMPAD1 ) )
		hr = SetFullscreenMode( g_fullscreenModes[0] );	
	else if( IsToggleKeyDown( VK_NUMPAD2 ) )
		hr = SetFullscreenMode( g_fullscreenModes[1] );	
	else if( IsToggleKeyDown( VK_NUMPAD3 ) )
		hr = SetFullscreenMode( g_fullscreenModes[2] );
	else if( IsToggleKeyDown( VK_NUMPAD7 ) )
		hr = SetRenderTarget( 1 );
	else if( IsToggleKeyDown( VK_NUMPAD8 ) )
		hr = SetRenderTarget( 2 );
	else if( IsToggleKeyDown( VK_NUMPAD9 ) )
		hr = SetRenderTarget( 4 );

	if( FAILED( hr ) )
		return hr;

	return S_OK;
}



//-----------------------------------------------------------------------------
// Render()
// Rendert die Umgebung.
//-----------------------------------------------------------------------------
HRESULT Render( void )
{
	HRESULT hr = CheckForBufferMatch();

	if( FAILED( hr ) )
		return hr;

	if( !g_bViewsCreated )
	{
		hr = CreateViews();

		if( FAILED( hr ) )
			return hr;
	}

	FLOAT color[4] = { 0.0f, 0.0f, 1.0f, 1.0f };

	UINT clear = D3D10_CLEAR_DEPTH | D3D10_CLEAR_STENCIL;
	UINT syncInterval = 1;

	g_pContext->ClearRenderTargetView( g_pRenderTargetView, color );
	g_pContext->ClearDepthStencilView( g_pDepthStencilView, clear, 1.0f, 0 );

	hr = g_pSwapChain->Present( syncInterval, 0 );

	if( FAILED( hr ) )
		return hr;

	return S_OK;
}



//-----------------------------------------------------------------------------
// ReleaseViews()
// Gibt die Swapchain Ressourcen frei.
//-----------------------------------------------------------------------------
void ReleaseViews( void )
{
	SafeReleaseCom( g_pRenderTargetView );
	SafeReleaseCom( g_pDepthStencil );
	SafeReleaseCom( g_pDepthStencilView );

	g_bViewsCreated = false;
}



//-----------------------------------------------------------------------------
// Cleanup()
// Räumt alles auf.
//-----------------------------------------------------------------------------
void Cleanup( void )
{
	if( g_pSwapChain )
		SetWindowedMode( g_windowedMode );

	ReleaseViews();
	SafeReleaseCom( g_pSwapChain );

	SafeDeleteArray( g_pModeList );

	SafeReleaseCom( g_pFactory );
	SafeReleaseCom( g_pAdapter );
	SafeReleaseCom( g_pOutput );
	SafeReleaseCom( g_pDevice );
	SafeReleaseCom( g_pContext );

	UnregisterClass( L"WindowClass", g_hInstance );
}
Das funktioniert soweit bestens. Nun ist mir aber aufgefallen, dass wenn ich Multisampling eingeschaltet habe, es im Vollbildmodus ständig com_errors im Debugfenster gibt!

"Eine Ausnahme (erste Chance) bei 0x75419617 in D3D11 Tutorial.exe: Microsoft C++-Ausnahme: _com_error an Speicherposition 0x0023e834.."

Irgend ein interner Speicherfehler tritt dabei auf es gibt aber keinen Crash. Das Programm funktioniert bestens. Zu Testzwecken habe ich ein DXUT Sample von Microsoft getestet und da passiert das gleiche, sobald im Vollbildmodus Multisampling eingeschaltet wird.

Kann ich diese Warnung ignorieren?

Vielen herzlichen Dank.
Benutzeravatar
Aramis
Moderator
Beiträge: 1458
Registriert: 25.02.2009, 19:50
Echter Name: Alexander Gessler
Wohnort: 2016
Kontaktdaten:

Re: Multisampling -> com_error

Beitrag von Aramis »

Hallo und herzlich willkommen im Forum!

Hast du Grafiktreiber / D3D9 Runtime auf den neuesten Stand gebracht?
Mabuntu
Beiträge: 3
Registriert: 10.08.2010, 20:22
Echter Name: Matej Kostalek

Re: Multisampling -> com_error

Beitrag von Mabuntu »

Hallo

Ist alles auf dem neusten Stand. Aber da das DXUT Sample die gleichen Warnungen ausspuckt, gehe ich mal davon aus das irgendwas mit meinem System zu tun hat.
Lustigerweise habe ich mit DXGI/D3D10/11 mehr Probleme gehabt als noch mit D3D9. Da könnte Microsoft die Doku noch verbesseren insbesondere zum Thema Vollbildmodus.

Grüsse
Benutzeravatar
Krishty
Establishment
Beiträge: 8350
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Multisampling -> com_error

Beitrag von Krishty »

Schalt mal die Debug-Runtime an – im Programmordner des DirectX-SDKs in DirectX-Utilities, DirectX Control Panel, Reiter Direct3D 10.x/11, Edit list…, dort deine Anwendung hinzufügen. Deinen Aufruf von ::D3D11CreateDevice() bereicherst du um ::D3D11_CREATE_DEVICE_DEBUG.

Falls es dann was Ernstes ist, wird es im Output-Fenster explizit erwähnt und erklärt werden – falls nicht, bleibt alles, wie es ist. Ich habe auch etliche Invalid parameter passed to C runtime function-Warnungen, wenn ich ein Device erzeuge …

Gruß, Ky
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Mabuntu
Beiträge: 3
Registriert: 10.08.2010, 20:22
Echter Name: Matej Kostalek

Re: Multisampling -> com_error

Beitrag von Mabuntu »

Gibt leider keine weitere Informationen zu meinem Problem aus. Immer noch dieses __com_error. Merkwürdig.

Nun ist mir noch was merkwürdiges aufgefallen zu meinem Programm. In der Funktion SetRenderTarget() wo mein Swapchain erstellt wird, habe ich einen Sleep() Befehl eingebaut. Dies musste ich tun damit der Fenstermodus korrekt übernommen wird. Wenn ich stattdessen diesen Befehl ingoriere und gleich wieder in den Vollbildmodus wechsle, wird die Desktopauflösung geändert und die bestehenden Fenstergrössen werden manipuliert.

Code: Alles auswählen

//-----------------------------------------------------------------------------
// SetRenderTarget()
// Konfiguriert den Renderbereich.
//-----------------------------------------------------------------------------
HRESULT SetRenderTarget( UINT sampleCount )
{
	HRESULT hr = S_OK;
	DXGI_SWAP_CHAIN_DESC desc = ZERO_ARRAY;
	BOOL bFullscreen = FALSE;

	if( g_pSwapChain )
	{
		g_pSwapChain->GetDesc( &desc );

		if( desc.SampleDesc.Count == sampleCount )
			return S_OK;

		bFullscreen = IsFullscreenMode();

		if( bFullscreen )
		{
			hr = SetWindowedMode( g_windowedMode );

			if( FAILED( hr ) )
				return hr;
		}

		ReleaseViews();
		SAFE_RELEASE_COM( g_pSwapChain );
	}

	hr = InitSwapChain( sampleCount );

	if( FAILED( hr ) )
		return hr;

	if( bFullscreen )
	{		
		Sleep( 1000 );
		hr = SetFullscreenMode( desc.BufferDesc );

		if( FAILED( hr ) )
			return hr;
	}

	return S_OK;
}
Funktioniert allerdings erst ab einer Sekunde! Alles sehr mekrwürdig.
Antworten