// 비디오 모드 전환
BOOL SetDisplayMode( HWND hWnd, DWORD Width, DWORD Height, DWORD BPP )
{
    // Set Cooperative Level

	smTextureBPP = BPP;

	if ( WindowMode ) return SetDisplayModeWin( hWnd , Width , Height , BPP );
	
    HRESULT hresult = lpDD->SetCooperativeLevel( hWnd,
                                                  DDSCL_EXCLUSIVE |
                                                  DDSCL_FULLSCREEN |
												  DDSCL_ALLOWMODEX );
    if ( hresult != DD_OK )
	{
		MESSAGE( "lpDD->SetCooperativeLevel" );
        return FALSE;
	}


    // 풀화면 모드로 전환
    hresult = lpDD->SetDisplayMode( Width, Height, BPP, 0, 0 );
    if ( hresult != DD_OK )
	{
		MESSAGE( "lpDD3->SetDisplayMode" );
        return FALSE;
	}


    // Primary Surface 생성
    DDSURFACEDESC2 ddsd;
    ZeroMemory( &ddsd, sizeof(ddsd) );

    ddsd.dwSize             = sizeof(ddsd);
    ddsd.dwBackBufferCount  = 1;
    ddsd.dwFlags            = DDSD_CAPS |
                              DDSD_BACKBUFFERCOUNT;
    ddsd.ddsCaps.dwCaps     = DDSCAPS_PRIMARYSURFACE |
                              DDSCAPS_FLIP |
                              DDSCAPS_COMPLEX |
                              DDSCAPS_VIDEOMEMORY |
                              DDSCAPS_3DDEVICE;

    // Primary surface 생성
    hresult = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
    if ( hresult != DD_OK )
	{
		MESSAGE( "lpDD->CreateSurface(lpDDSPrimary)" );
        return FALSE;
	}

    // Back Surface 생성(?)
    DDSCAPS2 ddscaps;
    ddscaps.dwCaps = DDSCAPS_BACKBUFFER;
    hresult = lpDDSPrimary->GetAttachedSurface( &ddscaps, &lpDDSBack );
    if ( hresult != DD_OK )
	{
		MESSAGE( "lpDDSPrimary->GetAttachedSurface" );
        return FALSE;
	}


	//////////// 클리퍼 생성 ////////////////////////
	lpDD->CreateClipper( 0, &lpDDClipper , NULL );
	lpDDClipper->SetHWnd( 0, hWnd );
	lpDDSPrimary->SetClipper( lpDDClipper );
	lpDDClipper->Release();



    // z-buffer Surface 생성
    ZeroMemory( &ddsd, sizeof(ddsd) );
    ddsd.dwSize            = sizeof(ddsd);
    ddsd.dwFlags           = DDSD_CAPS |
                             DDSD_WIDTH |
                             DDSD_HEIGHT |
                             DDSD_PIXELFORMAT;
    ddsd.dwWidth           = Width;
    ddsd.dwHeight          = Height;

	lpD3D->EnumZBufferFormats( IID_IDirect3DHALDevice , EnumZBufferCallback , (VOID *)&ddsd.ddpfPixelFormat );

	//######################################################################################
	//작 성 자 : 오 영 석
	::CopyMemory( &g_ddpfPixelFormatZ, &ddsd.ddpfPixelFormat, sizeof(g_ddpfPixelFormatZ) );
	//######################################################################################

    // 하드웨어 이면 z-buffer를 비디오 메모리에 만든다.
    if ( lpD3DDeviceDesc->bIsHardware )
        ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY;
    else
        ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_SYSTEMMEMORY;

    // Create the ZBuffer surface.
    hresult = lpDD->CreateSurface( &ddsd, &lpDDSZBuffer, NULL );
    if ( hresult != DD_OK )
	{
		MESSAGE( "lpDD2->CreateSurface(lpDDSZBuffer)" );
        return FALSE;
	}

    // Back Surface에 Z-buffer를 붙인다.
    hresult = lpDDSBack->AddAttachedSurface( lpDDSZBuffer );
    if ( hresult != DD_OK )
	{
		MESSAGE( "lpDDSBack->AddAttachedSurface" );
        return FALSE;
	}

    // Direct3D Device 생성
    hresult = lpD3D->CreateDevice( lpD3DDeviceDesc->guid,
                                    lpDDSBack,
                                    &lpD3DDevice,
									NULL );
    if ( hresult != D3D_OK )
	{
		MESSAGE( "lpD3D->CreateDevice" );
        return FALSE;
	}

    // Viewport 크기 설정
    D3DRect.x1 = 0;
    D3DRect.y1 = 0;
    D3DRect.x2 = Width;
    D3DRect.y2 = Height;

	smScreenWidth = Width;
	smScreenHeight = Height;

    return TRUE;
}
// 비디오 모드 전환
BOOL SetDisplayModeWin( HWND hWnd, DWORD Width, DWORD Height, DWORD BPP )
{
    // Set Cooperative Level

	
    HRESULT hresult = lpDD->SetCooperativeLevel( hWnd,DDSCL_NORMAL );

    if ( hresult != DD_OK )
	{
		MESSAGE( "lpDD->SetCooperativeLevel" );
        return FALSE;
	}


    // Primary Surface 생성
    DDSURFACEDESC2 ddsd;
    ZeroMemory( &ddsd, sizeof( ddsd ) );

    ddsd.dwSize             = sizeof(ddsd);
    ddsd.ddsCaps.dwCaps     = DDSCAPS_PRIMARYSURFACE |
                              DDSCAPS_3DDEVICE;

    // Primary surface 생성
    hresult = lpDD->CreateSurface( &ddsd, &lpDDSPrimary, NULL );
    if ( hresult != DD_OK )
	{
		MESSAGE( "lpDD2->CreateSurface(lpDDSPrimary)" );
        return FALSE;
	}


	int w,h;
	RECT lpRect;
	GetWindowRect( GetDesktopWindow() , &lpRect );
	w = lpRect.right - lpRect.left;
	h = lpRect.bottom - lpRect.top;

	// 백 버퍼 1 생성
    ZeroMemory( &ddsd, sizeof(ddsd) );
	ddsd.dwSize=sizeof(ddsd);
    ddsd.dwFlags=DDSD_CAPS|DDSD_HEIGHT|DDSD_WIDTH;
    ddsd.ddsCaps.dwCaps=DDSCAPS_OFFSCREENPLAIN|DDSCAPS_3DDEVICE| DDSCAPS_VIDEOMEMORY;
    ddsd.dwWidth  = w;
    ddsd.dwHeight = h;
    lpDD->CreateSurface(&ddsd,&lpDDSBack,NULL);

	lpDD->CreateClipper( 0, &lpDDClipper , NULL );
	lpDDClipper->SetHWnd( 0, hWnd );
	lpDDSPrimary->SetClipper( lpDDClipper );
	lpDDClipper->Release();


	DDPIXELFORMAT	ddpx;
    // z-buffer Surface 생성
    ZeroMemory( &ddsd, sizeof(ddsd) );
    ddsd.dwSize            = sizeof(ddsd);
    ddsd.dwFlags           = DDSD_CAPS |
                             DDSD_WIDTH |
                             DDSD_HEIGHT|
                             DDSD_PIXELFORMAT;

    ddsd.dwWidth           = w;
    ddsd.dwHeight          = h;

	lpD3D->EnumZBufferFormats( lpD3DDeviceDesc->guid , EnumZBufferCallback , (VOID *)&ddpx );

	memcpy( &ddsd.ddpfPixelFormat , &ddpx , sizeof( DDPIXELFORMAT ) );

	//######################################################################################
	//작 성 자 : 오 영 석
	::CopyMemory( &g_ddpfPixelFormatZ, &ddsd.ddpfPixelFormat, sizeof(g_ddpfPixelFormatZ) );
	//######################################################################################

    // 하드웨어 이면 z-buffer를 비디오 메모리에 만든다.
    if ( lpD3DDeviceDesc->bIsHardware )
        ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_VIDEOMEMORY;
    else
        ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_SYSTEMMEMORY;

    // Create the ZBuffer surface.
    hresult = lpDD->CreateSurface( &ddsd, &lpDDSZBuffer, NULL );
    if ( hresult != DD_OK )
	{
		MESSAGE( "lpDD2->CreateSurface(lpDDSZBuffer)" );
        return FALSE;
	}

    // Back Surface에 Z-buffer를 붙인다.
    hresult = lpDDSBack->AddAttachedSurface( lpDDSZBuffer );
    if ( hresult != DD_OK )
	{
		MESSAGE( "lpDDSBack->AddAttachedSurface" );
        return FALSE;
	}

    // Direct3D Device 생성
    hresult = lpD3D->CreateDevice( lpD3DDeviceDesc->guid,
									lpDDSBack,
									&lpD3DDevice,
									NULL );
    if ( hresult != D3D_OK )
	{
		MESSAGE( "lpD3D->CreateDevice" );
        return FALSE;
	}

    // Viewport 크기 설정
    D3DRect.x1 = 0;
    D3DRect.y1 = 0;
    D3DRect.x2 = w;
    D3DRect.y2 = h;

	smScreenWidth = Width;
	smScreenHeight = Height;

	return TRUE;
}
Exemple #3
0
/***************************************************************************\
  Initializes Direct3D.
\***************************************************************************/
int IMR_DirectXInterface::InitDirect3D(LPDIRECTDRAWSURFACE4 Target)
{
int err;
D3DVIEWPORT2   PortInitData;
DDPIXELFORMAT  ZBufferPixelFormat;  
DDSURFACEDESC2 ZBufferDesc, TargetDesc;
D3DDEVICEDESC  HALDesc, HELDesc;
int DeviceFound = FALSE, FormatFound = FALSE;

// Make sure DirectDraw is active:
if (!Flags.DirectDrawActive)
    {
    IMR_SetErrorText("IMR_DirectXInterface::InitDirect3D(): DirectDraw not initialized!");
    return IMRERR_NOTREADY;
     }

// Make sure we have a target surface:
if (!Target)
    {
    IMR_SetErrorText("IMR_DirectXInterface::InitDirect3D(): NULL target specified!");
    return IMRERR_NODATA;
     }

// Get target size info:
TargetDesc.dwSize = sizeof(TargetDesc);
Target->GetSurfaceDesc(&TargetDesc);

// Release all Direct3D interfaces:
if (Direct3DViewport)
    {
    Direct3DViewport->Release();
    Direct3DViewport = NULL;
     }
if (Direct3DDevice)
    {
    Direct3DDevice->Release();
    Direct3DDevice = NULL;
     }
if (Direct3D)
    {
    Direct3D->Release();
    Direct3D = NULL;
     }
Flags.Direct3DActive = 0;

// Now get a new Direct3D3 interface:
DirectDraw->QueryInterface(IID_IDirect3D3, (void **)&Direct3D);
if (err != DD_OK)
    {
    IMR_SetErrorText("IMR_DirectXInterface::InitDirect3D(): 1 DXERR: %s", IMR_MsgFromDXErr(err));
    return IMRERR_DIRECTX;
     }

// Enumerate the devices and find one to use:
err = Direct3D->EnumDevices(DeviceCallback, &DeviceFound);
if (err != D3D_OK)
    {
    IMR_SetErrorText("IMR_DirectXInterface::InitDirect3D(): 2 DXERR: %s", IMR_MsgFromDXErr(err));
    return IMRERR_DIRECTX;
     }
if (!DeviceFound) 
    { 
    IMR_SetErrorText("IMR_DirectXInterface::InitDirect3D(): No usable rendering devices!");
    return IMRERR_DIRECTX;
     }

// Find a pixel format for our z-buffer and verify that it worked:
Direct3D->EnumZBufferFormats(Direct3DDeviceInfo.Guid, ZBufferCallback, (void *)&ZBufferPixelFormat);
if (ZBufferPixelFormat.dwSize != sizeof(DDPIXELFORMAT))
    {
    IMR_SetErrorText("IMR_DirectXInterface::InitDirect3D(): Couldn't find Z-Buffer pixel format!");
    return IMRERR_DIRECTX;
     }

// Create a Z-Buffer:
ZeroMemory((void *)&ZBufferDesc, sizeof(ZBufferDesc));
ZBufferDesc.dwSize = sizeof(ZBufferDesc);
ZBufferDesc.dwFlags = DDSD_CAPS | DDSD_WIDTH | DDSD_HEIGHT | DDSD_PIXELFORMAT;
ZBufferDesc.ddsCaps.dwCaps = DDSCAPS_ZBUFFER;
ZBufferDesc.dwWidth = TargetDesc.dwWidth;
ZBufferDesc.dwHeight = TargetDesc.dwHeight;
memcpy(&ZBufferDesc.ddpfPixelFormat, &ZBufferPixelFormat, sizeof(DDPIXELFORMAT));
if (IsEqualIID(Direct3DDeviceInfo.Guid, IID_IDirect3DHALDevice))
    ZBufferDesc.ddsCaps.dwCaps |= DDSCAPS_VIDEOMEMORY;
else
    ZBufferDesc.ddsCaps.dwCaps |= DDSCAPS_SYSTEMMEMORY; 
err = DirectDraw->CreateSurface(&ZBufferDesc, &DDZBuffer, NULL);
if (err != DD_OK)
    {
    IMR_SetErrorText("IMR_DirectXInterface::InitDirect3D(): 3 DXERR: %s", IMR_MsgFromDXErr(err));
    return IMRERR_DIRECTX;
     }

// Now attach the Z-buffer to the target surface:
err = Target->AddAttachedSurface(DDZBuffer);
if (err != DD_OK)
    {
    IMR_SetErrorText("IMR_DirectXInterface::InitDirect3D(): 4 DXERR: %s", IMR_MsgFromDXErr(err));
    return IMRERR_DIRECTX;
     }

// Now create the device:
err = Direct3D->CreateDevice(Direct3DDeviceInfo.Guid, Target, &Direct3DDevice, NULL);
if (err != D3D_OK)
    {
    IMR_SetErrorText("IMR_DirectXInterface::InitDirect3D(): 5 DXERR: %s", IMR_MsgFromDXErr(err));
    return IMRERR_DIRECTX;
     }
 
// Setup the device:
Direct3DDevice->SetRenderState(D3DRENDERSTATE_ZENABLE, D3DZB_TRUE);
Direct3DDevice->SetRenderState(D3DRENDERSTATE_SHADEMODE, D3DSHADE_GOURAUD);
Direct3DDevice->SetRenderState(D3DRENDERSTATE_CULLMODE, D3DCULL_NONE);
Direct3DDevice->SetLightState(D3DLIGHTSTATE_MATERIAL, NULL);

// Make sure this device can handle our textures:
Direct3DDevice->EnumTextureFormats(TextureFormatCallback, (void *)&FormatFound);
if (!FormatFound)
    {
    IMR_SetErrorText("IMR_DirectXInterface::InitDirect3D(): No acceptable texture formats found!");
    return IMRERR_DIRECTX;
     }

// Now create a viewport init structure:
ZeroMemory(&PortInitData, sizeof(D3DVIEWPORT2));
PortInitData.dwSize = sizeof(D3DVIEWPORT2);
PortInitData.dwX = 0;
PortInitData.dwY = 0;
PortInitData.dwWidth = TargetDesc.dwWidth;
PortInitData.dwHeight = TargetDesc.dwHeight;
PortInitData.dvClipX = 0;
PortInitData.dvClipY = 0;
PortInitData.dvClipWidth = TargetDesc.dwWidth;
PortInitData.dvClipHeight = TargetDesc.dwHeight;
PortInitData.dvMinZ = 0.0f;
PortInitData.dvMaxZ = 1.0f;

// Create the viewport:
err = Direct3D->CreateViewport(&Direct3DViewport, NULL);
if (err != D3D_OK)
    {
    IMR_SetErrorText("IMR_DirectXInterface::InitDirect3D(): 6 DXERR: %s", IMR_MsgFromDXErr(err));
    return IMRERR_DIRECTX;
     }

// Associate the viewport with the device:
Direct3DDevice->AddViewport(Direct3DViewport); 

// Set the parameters for the new viewport:
Direct3DViewport->SetViewport2(&PortInitData);

// Set the current viewport for the device:
Direct3DDevice->SetCurrentViewport(Direct3DViewport);

// Flag that Direct3D is up and running:
Flags.Direct3DActive = 1;

// Whew!  That's done, so return success:
return IMR_OK;
 }