VC++10 Screensaver w/DirectX

EDN Admin

Well-known member
Joined
Aug 7, 2010
Messages
12,794
Location
In the Machine
Ive attempted to write a screensaver in C++ with DirectX elements using Visual Studio 2010 with mixed success. First off, the program is written and compiled under Windows 7, but only seems to function under WindowsXP (on Windows 7 the screen only turns
black), and I have to put all related files in the System32 folder for it to work (the scr-file, x-files and textures). When I open the Screen Properties to change screensaver in WindowsXP I get an error that the program (the screensaver) has crashed, assuming
this has something to do with the preview it attempts to launch, no such error appears under Windows7, but as stated above, the screensaver only displays a black screen in Windows7.
Code:

<div style="color:Black;background-color:White; <pre>
<span style="color:Green; // Include header files
#include <windows.h>
#include <WindowsX.h>
#include <scrnsave.h>
#include <d3d9.h>
#include <d3dx9.h>

<span style="color:Green; // Include library files
#pragma comment(lib, <span style="color:#A31515; "ScrnSave.lib")
#pragma comment(lib, <span style="color:#A31515; "ComCtl32.lib")
#pragma comment (lib, <span style="color:#A31515; "d3d9.lib")
#pragma comment (lib, <span style="color:#A31515; "d3dx9.lib")

<span style="color:Green; // Define constants
#define TIMER 1

<span style="color:Green; // Function Prototypes
<span style="color:Blue; void initD3D(HWND hWnd);
<span style="color:Blue; void render_frame(<span style="color:Blue; void);
<span style="color:Blue; void cleanD3D(<span style="color:Blue; void);
<span style="color:Blue; void init_graphics(<span style="color:Blue; void);
<span style="color:Blue; void init_light(<span style="color:Blue; void);

<span style="color:Green; // Global variables
LPDIRECT3D9 d3d;
LPDIRECT3DDEVICE9 d3ddev;
LPD3DXMESH meshTellus;
LPD3DXMESH meshSpace;
D3DMATERIAL9* materialTellus;
D3DMATERIAL9* materialSpace;
LPDIRECT3DTEXTURE9* textureTellus;
LPDIRECT3DTEXTURE9* textureSpace;
DWORD numMaterialsTellus;
DWORD numMaterialsSpace;
DEVMODE screen;
<span style="color:Blue; int scr_width;
<span style="color:Blue; int scr_height;

<span style="color:Green; // Entry point
LRESULT WINAPI ScreenSaverProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
<span style="color:Green; // Handle screensaver messages
<span style="color:Blue; switch(message)
{
<span style="color:Blue; case WM_CREATE: <span style="color:Green; // Create window and initialize components
<span style="color:Green; // Get resolution
EnumDisplaySettings(NULL, ENUM_CURRENT_SETTINGS, &screen);
scr_width = screen.dmPelsWidth;
scr_height = screen.dmPelsHeight;
<span style="color:Green; // Set up and initialize Direct3D
initD3D(hWnd);
<span style="color:Green; // Create timer with timeout value (10)
SetTimer(hWnd, TIMER, 10, NULL);
<span style="color:Blue; return 0;

<span style="color:Blue; case WM_ERASEBKGND:
<span style="color:Blue; return 0;

<span style="color:Blue; case WM_TIMER: <span style="color:Green; // Render a frame
render_frame();
<span style="color:Blue; return 0;


<span style="color:Blue; case WM_DESTROY: <span style="color:Green; // Clean up
cleanD3D();
KillTimer(hWnd, TIMER); <span style="color:Green; // Destroy timer
<span style="color:Blue; return 0;
}
<span style="color:Blue; return DefScreenSaverProc(hWnd, message, wParam, lParam);
}

<span style="color:Green; // Settings window
BOOL WINAPI ScreenSaverConfigureDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
<span style="color:Green; // Dialog message handling
<span style="color:Blue; switch(message)
{
<span style="color:Blue; case WM_COMMAND:
<span style="color:Blue; switch(LOWORD(wParam))
{
<span style="color:Blue; case IDOK:
EndDialog(hDlg, LOWORD(wParam) == IDOK);
<span style="color:Blue; return <span style="color:Blue; true;
<span style="color:Blue; case IDCANCEL:
EndDialog(hDlg, LOWORD(wParam) == IDOK);
<span style="color:Blue; return <span style="color:Blue; true;
}
}
<span style="color:Blue; return <span style="color:Blue; false;
}

<span style="color:Green; // Special controls for settings
BOOL WINAPI RegisterDialogClasses(HANDLE hInst)
{
<span style="color:Blue; return <span style="color:Blue; true;
}

<span style="color:Green; // Initialize Direct3D
<span style="color:Blue; void initD3D(HWND hWnd) {
d3d = Direct3DCreate9(D3D_SDK_VERSION);

D3DPRESENT_PARAMETERS d3dpp;

ZeroMemory(&d3dpp, <span style="color:Blue; sizeof(d3dpp));
d3dpp.Windowed = FALSE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.hDeviceWindow = hWnd;
d3dpp.BackBufferFormat = D3DFMT_X8R8G8B8;
d3dpp.BackBufferWidth = scr_width;
d3dpp.BackBufferHeight = scr_height;
d3dpp.EnableAutoDepthStencil = TRUE;
d3dpp.AutoDepthStencilFormat = D3DFMT_D16;

<span style="color:Green; // Create a device class
d3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hWnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &d3ddev);

init_graphics();
init_light();

d3ddev->SetRenderState(D3DRS_ZENABLE, TRUE);
d3ddev->SetRenderState(D3DRS_AMBIENT, D3DCOLOR_XRGB(50, 50, 50));

d3ddev->SetSamplerState(0, D3DSAMP_MAXANISOTROPY, 8);
d3ddev->SetSamplerState(0, D3DSAMP_MINFILTER, D3DTEXF_ANISOTROPIC);
d3ddev->SetSamplerState(0, D3DSAMP_MAGFILTER, D3DTEXF_ANISOTROPIC);
d3ddev->SetSamplerState(0, D3DSAMP_MIPFILTER, D3DTEXF_ANISOTROPIC);
}

<span style="color:Green; // Render a single frame
<span style="color:Blue; void render_frame(<span style="color:Blue; void) {
d3ddev->Clear(0, NULL, D3DCLEAR_TARGET, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);
d3ddev->Clear(0, NULL, D3DCLEAR_ZBUFFER, D3DCOLOR_XRGB(0, 0, 0), 1.0f, 0);

d3ddev->BeginScene();

<span style="color:Green; // Set view transform
D3DXMATRIX matView;
D3DXMatrixLookAtLH(&matView, &D3DXVECTOR3(0.0f, 10.0f, 90.0f), &D3DXVECTOR3(0.0f, 0.0f, 0.0f), &D3DXVECTOR3(0.0f, 1.0f, 0.0f));
d3ddev->SetTransform(D3DTS_VIEW, &matView);

<span style="color:Green; // Set projection transform
D3DXMATRIX matProjection;
D3DXMatrixPerspectiveFovLH(&matProjection, D3DXToRadian(45), (FLOAT)scr_width / (FLOAT)scr_height, 1.0f, 100.0f);
d3ddev->SetTransform(D3DTS_PROJECTION, &matProjection);

<span style="color:Green; // Set world transform
<span style="color:Blue; static <span style="color:Blue; float index = 0.0f;
index += 0.005f;
D3DXMATRIX matRotate;
D3DXMATRIX matResize;
D3DXMATRIX matMove;

<span style="color:Green; // Resize
D3DXMatrixScaling(&matResize, 1.0f, 1.0f, 1.0f);
<span style="color:Green; // Rotate
D3DXMatrixRotationYawPitchRoll(&matRotate, index, 0, 0);
<span style="color:Green; // Apply transformations
d3ddev->SetTransform(D3DTS_WORLD, &(matResize*matRotate));

<span style="color:Green; // Draw mesh
<span style="color:Blue; for(DWORD i = 0; i < numMaterialsTellus; i++) {
d3ddev->SetMaterial(&materialTellus);
<span style="color:Blue; if(textureTellus != NULL)
d3ddev->SetTexture(0, textureTellus);
meshTellus->DrawSubset(i);
}

<span style="color:Green; // Transform "space"
D3DXMatrixScaling(&matResize, 12.0f, 12.0f, 12.0f);
D3DXMatrixTranslation(&matMove, 0.0f, -3.0f, 8.0f);
D3DXMatrixRotationYawPitchRoll(&matRotate, -(index/8), 0, 0);
d3ddev->SetTransform(D3DTS_WORLD, &(matRotate*matMove*matResize));
<span style="color:Green; // Draw "space"
<span style="color:Blue; for(DWORD i = 0; i < numMaterialsSpace; i++) {
d3ddev->SetMaterial(&materialSpace);
<span style="color:Blue; if(textureSpace != NULL)
d3ddev->SetTexture(0, textureSpace);
meshSpace->DrawSubset(i);
}

d3ddev->EndScene();

d3ddev->Present(NULL, NULL, NULL, NULL);
}

<span style="color:Green; // Clean up
<span style="color:Blue; void cleanD3D(<span style="color:Blue; void) {
meshTellus->Release();
meshSpace->Release();

d3ddev->Release();
d3d->Release();
}

<span style="color:Green; // Load models to Video-RAM
<span style="color:Blue; void init_graphics(<span style="color:Blue; void) {
LPD3DXBUFFER bufTellus;
LPD3DXBUFFER bufSpace;

D3DXLoadMeshFromX(<span style="color:#A31515; "tellus.X", D3DXMESH_SYSTEMMEM, d3ddev, NULL, &bufTellus, NULL, &numMaterialsTellus, &meshTellus);
D3DXLoadMeshFromX(<span style="color:#A31515; "universe.x", D3DXMESH_SYSTEMMEM, d3ddev, NULL, &bufSpace, NULL, &numMaterialsSpace, &meshSpace);

D3DXMATERIAL* tempMaterialsTellus = (D3DXMATERIAL*)bufTellus->GetBufferPointer();
D3DXMATERIAL* tempMaterialsSpace = (D3DXMATERIAL*)bufSpace->GetBufferPointer();

materialTellus = <span style="color:Blue; new D3DMATERIAL9[numMaterialsTellus];
materialSpace = <span style="color:Blue; new D3DMATERIAL9[numMaterialsSpace];
textureTellus = <span style="color:Blue; new LPDIRECT3DTEXTURE9[numMaterialsTellus];
textureSpace = <span style="color:Blue; new LPDIRECT3DTEXTURE9[numMaterialsSpace];

<span style="color:Blue; for(DWORD i = 0; i < numMaterialsTellus; i++) {
materialTellus = tempMaterialsTellus.MatD3D;
materialTellus.Ambient = materialTellus.Diffuse;
<span style="color:Blue; if(FAILED(D3DXCreateTextureFromFileA(d3ddev, tempMaterialsTellus.pTextureFilename, &textureTellus)))
textureTellus=NULL;
}
<span style="color:Blue; for(DWORD i = 0; i < numMaterialsSpace; i++) {
materialSpace = tempMaterialsSpace.MatD3D;
materialSpace.Ambient = materialSpace.Diffuse;
<span style="color:Blue; if(FAILED(D3DXCreateTextureFromFileA(d3ddev, tempMaterialsSpace.pTextureFilename, &textureSpace)))
textureSpace=NULL;
}
}

<span style="color:Green; // Set up lighting
<span style="color:Blue; void init_light(<span style="color:Blue; void) {
D3DLIGHT9 light;

ZeroMemory(&light, <span style="color:Blue; sizeof(light));

light.Type = D3DLIGHT_DIRECTIONAL;
light.Diffuse = D3DXCOLOR(0.9f, 0.9f, 0.9f, 1.0f);
light.Direction = D3DXVECTOR3(-1.0f, -0.3f, -1.0f);

d3ddev->SetLight(0, &light);
d3ddev->LightEnable(0, TRUE);
}
[/code]

Ive tested the textures and meshes in a separate program which seems to work fine on both WinXP and Win7.
Question is; is there anything that can be done to avoid the problems mentioned above?
Thanks in advance.

View the full article
 
Back
Top