I ahve developed a simple Direct3D8 app. It works on Windows Server 2003, Windows XP, but not on Windows XP version 2002 and -.
Maybe smbody help me to find out the reason of crash:
moframecount.h
#define STRICT
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <d3dx8core.h> // fur Direct3D 8
#include <mmsystem.h> // fur timeSetEvent()
#include <time.h> // fur time()
#include <stdio.h> // fur sprintf()
#include "moframecount.h"
#define DD_DEBUG
#undef DD_DEBUG
// my defines
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif
#define DD_PI M_PI
#define DD_CLASSNAME "ddscreensaver1"
#define DD_DOTS_MAX 16
#define DD_TIME_CALC 10
int mov = 2;
#define DD_FONT_SIZE 16
#define DD_TEXT_INTERVAL 50
#define DD_WINCHECK(func) if(!(func)) return -1
#define DD_CHECK(func) if(FAILED((func))) { MessageBox(hwnd, "Application will now close", NULL, MB_OK | MB_ICONSTOP); return -1; }
#define DD_DCHECK(func) DD_CHECK((func)); ++dd_app_init;
#define DD_RELEASE(lp) (lp)->Release();(lp)=NULL;--dd_app_init
// global vars
int dd_app_init;
int slow_pc;
char Slow[128];
char* pSlow = Slow;
int draw_text = DD_TEXT_INTERVAL;
POINT screen;
int mouse_init;
LPARAM mouse_pos;
MMRESULT hTimer;
char status[256];
RECT rect;
LPDIRECT3DDEVICE8 lpd3dd;
LPDIRECT3DVERTEXBUFFER8 lpd3dvb;
LPD3DXFONT lpd3dxfont;
moFrameCount fc;
char* cData;
int Semaphore;
CRITICAL_SECTION cs;
PAINTSTRUCT ps;
struct DD_LINE
{
typedef float DD_TYPE_ANGLE;
struct DD_VERTEX
{
FLOAT x, y, z, rhw; // The transformed position for the vertex.
DWORD color; // The vertex color.
} vertex;
bool XSign, YSign;
DD_TYPE_ANGLE angle;
} *line; // масив точок
// calculate
void CALLBACK CalculateFrame(UINT uTimerID, UINT, DWORD_PTR, DWORD_PTR, DWORD_PTR)
{
if(Semaphore)
{
slow_pc = 1;
return;
}
Semaphore = 1;
EnterCriticalSection(&cs);
int j = 0;
for(; j < DD_DOTS_MAX-1; ++j)
{
if(line[j].vertex.x <= 0 || line[j].vertex.x >= screen.x)
{
line[j].XSign = !line[j].XSign;
}
if(line[j].vertex.y <= 0 || line[j].vertex.y >= screen.y)
{
line[j].YSign = !line[j].YSign;
}
line[j].XSign ? line[j].vertex.x += cosf(line[j].angle)*mov : line[j].vertex.x -= cosf(line[j].angle)*mov;//= (rand() % screen.x);
line[j].YSign ? line[j].vertex.y += sinf(line[j].angle)*mov : line[j].vertex.y -= sinf(line[j].angle)*mov;//= (rand() % screen.x);
}
line[DD_DOTS_MAX-1].vertex.x = line[0].vertex.x;
line[DD_DOTS_MAX-1].vertex.y = line[0].vertex.y;
Semaphore = 0;
LeaveCriticalSection(&cs);
}
// win-prok
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg, WPARAM w, LPARAM l)
{
switch(msg)
{
case WM_CREATE:
// створюємо точки
line = new DD_LINE[DD_DOTS_MAX];
// останню точку не рухати, бо вона і так буде копіюватись із першої
for(int j = 0; j < DD_DOTS_MAX; ++j)
{
line[j].vertex.x = (FLOAT)(rand() % screen.x);
line[j].vertex.y = (FLOAT)(rand() % screen.y);
line[j].vertex.z = 0.5f;
line[j].vertex.rhw = 1.0f;
line[j].vertex.color = rand()*(INFINITE/RAND_MAX);
line[j].angle = (rand()%360)*(float)DD_PI/180;
}
line[DD_DOTS_MAX-1].vertex.z = line[0].vertex.z;
line[DD_DOTS_MAX-1].vertex.rhw = line[0].vertex.rhw;
line[DD_DOTS_MAX-1].vertex.color = line[0].vertex.color;
rect.left = 0;
rect.bottom = screen.y;
rect.top = rect.bottom - DD_FONT_SIZE*2;
rect.right = screen.x;
InitializeCriticalSection(&cs);
timeBeginPeriod(1);
hTimer = timeSetEvent(DD_TIME_CALC, 0, (LPTIMECALLBACK)CalculateFrame, (DWORD_PTR)0, TIME_KILL_SYNCHRONOUS | TIME_PERIODIC);
break;
case WM_MOUSEMOVE:
if(!mouse_init)
{
++mouse_init;
mouse_pos = l;
return DefWindowProc(hwnd, msg, w, l);
}
if(mouse_pos == l)
break;
case WM_KEYDOWN:
case WM_KEYUP:
case WM_SYSKEYDOWN:
case WM_SYSKEYUP:
case WM_LBUTTONDOWN:
case WM_RBUTTONDOWN:
case WM_MBUTTONDOWN:
#ifndef DD_DEBUG
SendMessage(hwnd, WM_DESTROY, 0, 0);
#endif
break;
case WM_DESTROY:
timeKillEvent(hTimer);
timeEndPeriod(1);
DeleteCriticalSection(&cs);
// видаляємо точки
delete[] line;
PostQuitMessage(0);
break;
case WM_PAINT:
// BeginPaint(hwnd, &ps);
// EndPaint(hwnd, &ps);
DD_CHECK(lpd3dd->Clear(0, NULL, D3DCLEAR_TARGET, (D3DCOLOR)0, 1.0f, 0));
void* ppbData;
//sizeof(DD_LINE::DD_VERTEX) * DD_DOTS_MAX
DD_CHECK(lpd3dvb->Lock(0, 0, (BYTE **)&(ppbData), 0));//sizeof(vertex)
for(int k = 0; k < DD_DOTS_MAX; ++k)
{
memcpy(ppbData, &(line[k].vertex), sizeof(DD_LINE::DD_VERTEX));
cData = (char *)ppbData;
cData += sizeof(DD_LINE::DD_VERTEX);
ppbData = cData;
}
DD_CHECK(lpd3dvb->Unlock());
DD_CHECK(lpd3dd->BeginScene());
DD_CHECK(lpd3dd->SetStreamSource(0, lpd3dvb, sizeof(DD_LINE::DD_VERTEX)));
DD_CHECK(lpd3dd->SetVertexShader(D3DFVF_XYZRHW | D3DFVF_DIFFUSE));
DD_CHECK(lpd3dd->DrawPrimitive(D3DPT_LINESTRIP, 0, DD_DOTS_MAX-1));
fc.Inc();
if(draw_text++ == DD_TEXT_INTERVAL)
{
if(slow_pc)
{
strcpy(pSlow, "; Your PC too slow for rendering frames");
slow_pc = 0;
}
sprintf(status, "dd screensaver_lines; beta; 2005/05/18, 2005/05/19; requires Direct3D 8, Direct3DX%s; rendering %d fps", pSlow, fc.Get());
draw_text = 0;
}
lpd3dxfont->DrawText(status, (INT)strlen(status), &rect, 0, 0xFFFFFFFF);
DD_CHECK(lpd3dd->EndScene());
DD_CHECK(lpd3dd->Present(NULL, NULL, NULL, NULL));
break;
default:
return DefWindowProc(hwnd, msg, w, l);
}
return 0;
}
// winmain
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE, LPSTR cmd, int)
{
srand((unsigned)time(NULL));
WNDCLASS wc = { 0, WndProc, 0, 0, hInst, (HICON)NULL, (HCURSOR)NULL, (HBRUSH)(COLOR_BACKGROUND+1), 0, DD_CLASSNAME };
DD_WINCHECK(RegisterClass(&wc));
screen.x = GetSystemMetrics(SM_CXSCREEN);
screen.y = GetSystemMetrics(SM_CYSCREEN);
HWND hwnd = CreateWindow(DD_CLASSNAME, NULL, WS_POPUP | WS_VISIBLE, 0, 0, screen.x, screen.y, GetDesktopWindow(), (HMENU)NULL, hInst, NULL);
DD_WINCHECK(hwnd);
ShowCursor(FALSE);
// створюєм Direct3D
LPDIRECT3D8 lpd3d = Direct3DCreate8(D3D_SDK_VERSION);
DD_WINCHECK(lpd3d);
// дістаєм інформацію про екран
D3DDISPLAYMODE d3ddm;
DD_DCHECK(lpd3d->GetAdapterDisplayMode(D3DADAPTER_DEFAULT, &d3ddm));
// опції для application
D3DPRESENT_PARAMETERS d3dpp;
memset(&d3dpp, 0, sizeof(d3dpp));
d3dpp.Windowed = TRUE;
d3dpp.SwapEffect = D3DSWAPEFFECT_DISCARD;
d3dpp.BackBufferFormat = d3ddm.Format;
d3dpp.BackBufferCount = 1;
d3dpp.Flags = D3DPRESENTFLAG_LOCKABLE_BACKBUFFER;
// d3dpp.MultiSampleType = D3DMULTISAMPLE_NONE
// створюєм device
if(D3DERR_NOTAVAILABLE == lpd3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_HARDWARE_VERTEXPROCESSING, &d3dpp, &lpd3dd))
if(D3DERR_NOTAVAILABLE == lpd3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_MIXED_VERTEXPROCESSING, &d3dpp, &lpd3dd))
if(D3DERR_NOTAVAILABLE == lpd3d->CreateDevice(D3DADAPTER_DEFAULT, D3DDEVTYPE_HAL, hwnd, D3DCREATE_SOFTWARE_VERTEXPROCESSING, &d3dpp, &lpd3dd))
return -1;
DD_DCHECK(D3D_OK);
/*
DD_CHECK(lpd3dd->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE));
DD_CHECK(lpd3dd->SetRenderState(D3DRS_DITHERENABLE, TRUE));
DD_CHECK(lpd3dd->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCCOLOR));
DD_CHECK(lpd3dd->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCCOLOR));
*/
DD_DCHECK(lpd3dd->CreateVertexBuffer(DD_DOTS_MAX * sizeof(DD_LINE::DD_VERTEX), 0, D3DFVF_XYZRHW | D3DFVF_DIFFUSE, D3DPOOL_DEFAULT, &lpd3dvb));
HFONT hFont = CreateFont(DD_FONT_SIZE, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, VARIABLE_PITCH | FF_SWISS, NULL);
DD_DCHECK(D3DXCreateFont(lpd3dd, hFont, &lpd3dxfont));
MSG msg;
while(GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
DD_RELEASE(lpd3dxfont);
DD_RELEASE(lpd3dvb);
DD_RELEASE(lpd3dd);
DD_RELEASE(lpd3d);
return (int)(msg.wParam ? msg.wParam : -dd_app_init);
}