#include <windows.h> // Include the Windows header file that’s needed for all Windows applications
#include <d3d9.h> // direct3D_9
#include <d3dx9.h>
#include <dxerr9.h>
#include <stdio.h>
#include <crtdbg.h>
#pragma comment(lib, "d3d9.lib") //include d3d libraries to linker
#pragma comment(lib, "d3dx9.lib") //include d3d libraries to linker
#pragma comment(lib, "dxerr9.lib")
////////////////////
// global variables
////////////////////
HINSTANCE hInst; // application instance
HWND wndHandle; // application window handle
LPDIRECT3D9 pD3D; // the Direct3D Object (interface to create d3d devices, and more)
LPDIRECT3DDEVICE9 pd3dDevice; // the Direct3D Device (a specific d3d device that matches our system)
// forward declarations
/********************************/
bool initWindow( HINSTANCE hInstance ); //
LRESULT CALLBACK WndProc( HWND, UINT, WPARAM, LPARAM ); //our callback function
// DirectX functions
/*****************/
bool initDirect3D();
void render(void);
// This is winmain, the main entry point for Windows applications
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow )
// --------------
{
if (!initWindow(hInstance)) // Create/Initialize the window
{
MessageBox(NULL, "Unable to create window", "ERROR", MB_OK);
return false;
}
if (!initDirect3D()) //Create/Initialize a direct3D obj
{
MessageBox(NULL, "Unable to init Direct3D", "ERROR", MB_OK);
return false;
}
// Main message loop:
MSG msg;
ZeroMemory( &msg, sizeof(msg) );
while( msg.message!=WM_QUIT )
{
// Check the message queue
if( PeekMessage( &msg, NULL, 0U, 0U, PM_REMOVE ) )
{
TranslateMessage( &msg );
DispatchMessage( &msg );
}
else
{
render();
}
}
// release the device and the direct3D object
if( pd3dDevice != NULL)
pd3dDevice->Release();
if( pD3D != NULL)
pD3D->Release();
return (int) msg.wParam;
}
/******************************************************************************
* bool initWindow( HINSTANCE hInstance )
* initWindow (1) registers the window class for the application, (2) creates the window
******************************************************************************/
bool initWindow( HINSTANCE hInstance )
{
//(1) Define and register a WINDOW CLASS
WNDCLASSEX wcex;
// Fill in the WNDCLASSEX structure. This describes how the window will look to the system
wcex.cbSize = sizeof(WNDCLASSEX); // the size of the structure
wcex.style = CS_HREDRAW | CS_VREDRAW; // the class style
wcex.lpfnWndProc = (WNDPROC)WndProc; // the window procedure callback
wcex.cbClsExtra = 0; // extra bytes to allocate for this class
wcex.cbWndExtra = 0; // extra bytes to allocate for this instance
wcex.hInstance = hInstance; // handle to the application instance
wcex.hCursor = LoadCursor(NULL, IDC_ARROW); // the default cursor
wcex.hIcon = LoadIcon(NULL, IDI_APPLICATION); // icon to associate with the application
wcex.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);// the background color
wcex.hIconSm = LoadIcon(NULL, IDI_WINLOGO);
wcex.lpszMenuName = NULL; // the resource name for the menu
wcex.lpszClassName = "DirectXExample"; // the class name being created
RegisterClassEx(&wcex);
// Create the window
wndHandle = CreateWindow(
"DirectXExample", // the window class to use
"DirectXExample", // the title bar text
WS_OVERLAPPEDWINDOW | WS_VISIBLE, // the window style
CW_USEDEFAULT, // the starting x coordinate
CW_USEDEFAULT, // the starting y coordinate
640, // the pixel width of the window
480, // the pixel height of the window
NULL, // the parent window; NULL for desktop
NULL, // the menu for the application; NULL for none
hInstance, // the handle to the application instance
NULL); // no values passed to the window
// Make sure that the window handle that is created is valid
if (!wndHandle)
return false;
// Display the window on the screen
ShowWindow(wndHandle, SW_SHOW);
UpdateWindow(wndHandle);
return true;
}
//The window procedure, 'WndProc', handles events from the system that relate to your application.
/******************************************************************************
* LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
* The window procedure
******************************************************************************/
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
// Check any available messages from the queue
switch (message)
{
case WM_DESTROY:
PostQuitMessage(0);
break;
}
// Always return the message to the DefaultWindowProcedure for further processing
// The following Line DOES the actual creation, showing of window and HANDLES ANY WINDOW MSG
return DefWindowProc(hWnd, message, wParam, lParam);
}
/*********************************************************************
* initializes direct3D
*********************************************************************/
bool initDirect3D()
{
pD3D = NULL;
pd3dDevice = NULL;
// create the Direct3D object (if Ok pD3D should get a pointer to an IDirect3D9 interface)
if( NULL == ( pD3D = Direct3DCreate9( D3D_SDK_VERSION ) ) )
{
MessageBox(NULL, "E_FAIL Direct3DCreate9(D3D_SDK_VERSION) = NULL", "Error!",MB_ICONEXCLAMATION | MB_OK);
return false;
}
//--***********###########********* Interesting part BEGIN ***********###########*********
//--***********###########********* Interesting part BEGIN ***********###########*********
//Get the current display mode (in windowed mode this is the only format we can use)
D3DDISPLAYMODE d3ddm;
if(FAILED(pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm)))
{
MessageBox(NULL, "FAILED(pD3D->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm))", "Error!",MB_ICONEXCLAMATION | MB_OK);
}
/////////////
// What the hell!
/////////////
//Test if current display mode is actually usable (16bit/32bit colour on desktop)
HRESULT result1 = pD3D->CheckDeviceType( D3DADAPTER_DEFAULT, //adapter
D3DDEVTYPE_HAL, //hw or sw rendering (HAL/REF)
d3ddm.Format, //displayFormat
d3ddm.Format, //backBuffer format
TRUE ); //isWindowed
if (FAILED(result1))
{
MessageBox(NULL, DXGetErrorString9(result1), "Error!",MB_ICONEXCLAMATION | MB_OK);
MessageBox(NULL, "FAILED(Current display format not acceptable! \n Try to change desktop colour settings to 16bits!)", "Error!",MB_ICONEXCLAMATION | MB_OK);
exit(0);
}
//--***********###########********* Interesting part END ***********###########*********
//--***********###########********* Interesting part END ***********###########*********
//fill the presentation parameters structure
D3DPRESENT_PARAMETERS d3dpp;
ZeroMemory( &d3dpp, sizeof(d3dpp) );
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format; //16bit-checked with DirectXCapsViewer, supported in all screen sizes and both 2D and 3D
d3dpp.BackBufferHeight = d3ddm.Height;
d3dpp.BackBufferWidth = d3ddm.Width;
d3dpp.BackBufferCount = 1;
d3dpp.hDeviceWindow = wndHandle;
// create a default Direct3D device
HRESULT result = pD3D->CreateDevice( D3DADAPTER_DEFAULT, //number of the video adapter, primary video adapter = DEFAULT
D3DDEVTYPE_HAL, //device uses hardware acceleration and rasterization
//D3DDEVTYPE_REF, //The Microsoft reference rasterizer is used.
wndHandle, //This is the window to which this device will belong
D3DCREATE_SOFTWARE_VERTEXPROCESSING, //behaviour flag
&d3dpp,
&pd3dDevice );
if (FAILED(result))
{
MessageBox(NULL, DXGetErrorString9(result), "Error!",MB_ICONEXCLAMATION | MB_OK);
MessageBox(NULL, DXGetErrorDescription9(result), "Error!",MB_ICONEXCLAMATION | MB_OK);
return false;
}
return true;
}
/*********************************************************************
* render
*********************************************************************/
void render(void)
{
// check to make sure we have a valid Direct3D Device
if( NULL == pd3dDevice )
return;
// Clear the backbuffer to a blue color
pd3dDevice->Clear( 0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0,0,255), 1.0f, 0 );
// Present the backbuffer contents to the display
pd3dDevice->Present( NULL, NULL, NULL, NULL );
}
Why cant use "current display mode" if desktop=32-bit colour depth?
I am trying to create a Direct3D WINDOWED device using into presentation
parameters the current display settings. If the desktop is set to 16bits
colours then everything goes fine: CreateDevice succeeds. But if it is
32 bits, then it gives D3DERR_NOTAVAILABLE, and so does also CheckDeviceType!!
Of course i could just be happy with 16-bits colour and warn the user to switch
to 16bits mode from within my prog. However i would like to understand why is
this going wrong in first place!
By the way i tried to enumerate the video card capabilities and i see that
only "D3DFMT_R5G6B5" colour format is supported. But if i set the desktop
properties to use 32 bits colours, then i get D3DFMT_X8R8G8B8 as expected, but
then i cannot use neither R5G6B5 or X8R8G8B8 (curent display setting) to create
a device..! What is the problem????
Hereafter the code to reproduce the problem, "Interesting part BEGIN " is the
place to watch carefully, thanks for any help! :-))
This is not unusal for some devices, they simply don't support Direct3D in 32 bpp modes, only 2D acceleration via DirectDraw.
What garphics card do you have? I know older cards used to have some odd restrictions like this in windowed mode...
Hey guys, thanks for your posts. Well, my video card is a "3dfx Voodoo 3",
quite old indeed, but i experience the same identical problem at work, where
there's an intel integrated video card. None of them supports 32bpp. But even
then, why can the windows desktop be set at 32bpp and everything else work just
fine? Mah!..
Cheers
quite old indeed, but i experience the same identical problem at work, where
there's an intel integrated video card. None of them supports 32bpp. But even
then, why can the windows desktop be set at 32bpp and everything else work just
fine? Mah!..
Cheers
I'm guessin' Windows is 2D, so 32bit isn't so hard as 32bit 3D? =]
I guess the integrated gfx at work are pretty old too...
I guess the integrated gfx at work are pretty old too...
Hi Motocrossdoug, well.. you are right indeed about the 2D takes up less resources.. Actually i just need to do 2D graphics, but I'm forced to create a direct3D device anyways i'm afraid.
..by the way, if someone knows a way to force the desktop colour depth to 16 bits, that would be great too! I heard that you need to have full screen access to set the display mode you want independently of the desktop settings, but maybe there's a workaround. Any idea from someone that did this already is welcome.
Cheers
Cheers
d3dpp.Windowed = TRUE;d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD; d3dpp.BackBufferFormat = D3DFMT_UNKNOWNd3dpp.BackBufferHeight = 0;d3dpp.BackBufferWidth = 0; d3dpp.BackBufferCount = 1;d3dpp.hDeviceWindow = wndHandle;
Try this change and get rid of the GetAdapterDisplayMode and CheckDeviceType functions and see how that goes as that's the way I do it and get 32bpp for windowed apps.
After a little poking around on archive.org, looking at long past 3dfx.com pages, I found a FAQ for the Voodoo 3:
16. Why doesn't Voodoo3 support 32b rendering, or large textures, or 32b textures?
There are two reasons: frame rate and image quality. Frame rate is the single most important feature that a gaming platform can provide, and not just average frame rate but sustained frame rate. How many times have you been wiped out in a death match when your frame rate suddenly drops as a number of characters and weapons enter the scene? 32bpp rendering with full 32bpp frame buffer accesses requires twice the memory bandwidth of 16bpp frame buffer accesses regardless of the graphics engine: Higher bandwidth requirement means lower frame rate. As for image quality, we have gone to great lengths to make games look great in 16bpp mode. We actually do the rendering calculations internally at 32 bits to have full precision with the 16-bit operands. Then, instead of simply truncating the results to 16 bits for saving in the frame buffer, we use a proprietary filtering algorithm that retains nearly the full precision of the color value. The result is something that rivals ANY full 32-bit rendering. Except it goes a lot faster. We think that is what gamers are looking for.
16. Why doesn't Voodoo3 support 32b rendering, or large textures, or 32b textures?
There are two reasons: frame rate and image quality. Frame rate is the single most important feature that a gaming platform can provide, and not just average frame rate but sustained frame rate. How many times have you been wiped out in a death match when your frame rate suddenly drops as a number of characters and weapons enter the scene? 32bpp rendering with full 32bpp frame buffer accesses requires twice the memory bandwidth of 16bpp frame buffer accesses regardless of the graphics engine: Higher bandwidth requirement means lower frame rate. As for image quality, we have gone to great lengths to make games look great in 16bpp mode. We actually do the rendering calculations internally at 32 bits to have full precision with the 16-bit operands. Then, instead of simply truncating the results to 16 bits for saving in the frame buffer, we use a proprietary filtering algorithm that retains nearly the full precision of the color value. The result is something that rivals ANY full 32-bit rendering. Except it goes a lot faster. We think that is what gamers are looking for.
Ahahaha, I like that they claim that their 16 bit rivals any 32 bit setup... regardless of how good the algorithm and calculations are, 16 bit color is 16 bit color, you can tell the difference...
As far as a solution... If you only need 2D, and want 32bit support, it may be possible to not have to set up a 3D environment using DX7, before DirectDraw and Direct3D were unified (that was 8, right? <.<). Well, I'm uncertain of the specifics of this, but I think it should be possible...
As for forcing the desktop into a certain bit-depth, I did a quick search of the MSDN (probably not the best place, but eh... hoping for a clean function >.>) and found nothin'. I'd imagine the only way to do it would be to tell Windows to change it before you create the device and things... I'm pretty sure you can't do it yourself so long as Windows is managing the screen.
As far as a solution... If you only need 2D, and want 32bit support, it may be possible to not have to set up a 3D environment using DX7, before DirectDraw and Direct3D were unified (that was 8, right? <.<). Well, I'm uncertain of the specifics of this, but I think it should be possible...
As for forcing the desktop into a certain bit-depth, I did a quick search of the MSDN (probably not the best place, but eh... hoping for a clean function >.>) and found nothin'. I'd imagine the only way to do it would be to tell Windows to change it before you create the device and things... I'm pretty sure you can't do it yourself so long as Windows is managing the screen.
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement