📄 d3dmain.cpp
字号:
Msg("CreateSurface for system surface failed (SW).\0", ddrval);
return(FALSE);
}
}
// set the color key of this surface to black for the Blits
myDDSetColorKey(lpDDSurfaceSystem, RGB(0,0,0));
// create the Z buffer for the SW thread
memset(&ddsd, 0, sizeof(DDSURFACEDESC));
ddsd.dwSize = sizeof(DDSURFACEDESC);
ddsd.dwFlags = DDSD_CAPS | DDSD_HEIGHT | DDSD_WIDTH | DDSD_ZBUFFERBITDEPTH;
ddsd.ddsCaps.dwCaps = DDSCAPS_ZBUFFER | DDSCAPS_SYSTEMMEMORY;
ddsd.dwWidth = sizeX;
ddsd.dwHeight = sizeY;
ddsd.dwZBufferBitDepth = 16;
ddrval = lpDD_SW->CreateSurface(&ddsd, &lpDDZBufferSystem, NULL);
if (ddrval != DD_OK)
{
if (ddrval == DDERR_OUTOFMEMORY || ddrval == DDERR_OUTOFVIDEOMEMORY)
{
Msg("Not enough memory to create the Z-Buffer (SW).\0", ddrval);
return(FALSE);
}
else
{
Msg("CreateSurface for Z-Buffer failed (SW).\0", ddrval);
return(FALSE);
}
}
/*
Now we create the surface who'll hold the texture generated
by the SW thread in Frame N-1, this texture will be used in
Frame N to render two triangles by the HW thread.
*/
ddrval = createSwTexture();
if (ddrval != TRUE) return(FALSE);
// set color key of buffer in video memory to black for
// transparent texture mapping
myDDSetColorKey(lpDDTextureSurfaceSPOT, RGB(0,0,0));
// init the SW scene
ddrval = InitSwScene();
if (ddrval != TRUE)
{
Msg("init of SW data struct failed.\0", ddrval);
return(FALSE);
}
} // end of SW rendering initialization
// Create SW Thread
th = CreateThread (NULL, 0, (LPTHREAD_START_ROUTINE)DrawFrameSW,
NULL, CREATE_SUSPENDED, &dwThreadId);
SetThreadPriority(th, THREAD_PRIORITY_HIGHEST);
eventHandle = CreateEvent(NULL, TRUE, FALSE, "SW is Ready\0");
// setup synch events and resume SW thread
compositeHandle = CreateEvent(NULL, TRUE, FALSE, "Composite is Ready\0");
ResumeThread(th); // Start SW Thread going...
return TRUE;
}
/*
* CreateD3DApp
* Create all DirectDraw and Direct3D objects necessary to begin rendering.
* Add the list of D3D drivers to the file menu.
*/
static BOOL
CreateD3DApp(LPSTR lpCmdLine)
{
HMENU hmenu;
int i;
LPSTR option;
BOOL bOnlySystemMemory, bOnlyEmulation;
DWORD flags;
Defaults defaults;
/*
* Give D3DApp a list of textures to keep track of.
*/
D3DAppAddTexture("checker.ppm");
D3DAppAddTexture("tex2.ppm");
D3DAppAddTexture("tex7.ppm");
D3DAppAddTexture("win95.ppm");
/*
* Parse the command line in seach of one of the following options:
* systemmemory All surfaces should be created in system memory.
* Hardware DD and D3D devices are disabled, but
* debugging during the Win16 lock becomes possible.
* emulation Do not use hardware DD or D3D devices.
*/
bOnlySystemMemory = FALSE;
bOnlyEmulation = FALSE;
#if 0 // I don't want user to be able to change this
option = strtok(lpCmdLine, " -");
while(option != NULL ) {
if (!lstrcmp(option, "systemmemory")) {
bOnlySystemMemory = TRUE;
} else if (!lstrcmp(option, "emulation")) {
bOnlyEmulation = TRUE;
} else {
Msg("Invalid command line options given.\nLegal options: -systemmemory, -emulation\n");
return FALSE;
}
option = strtok(NULL, " -");
}
#endif
/*
* Set the flags to pass to the D3DApp creation based on command line
*/
flags = ((bOnlySystemMemory) ? D3DAPP_ONLYSYSTEMMEMORY : 0) |
((bOnlyEmulation) ? (D3DAPP_ONLYD3DEMULATION |
D3DAPP_ONLYDDEMULATION) : 0);
/*
* Create all the DirectDraw and D3D objects neccesary to render. The
* AfterDeviceCreated callback function is called by D3DApp to create the
* viewport and the example's execute buffers.
*/
if (!D3DAppCreateFromHWND(flags, myglobs.hWndMain,
myglobs.DDDriver[myglobs.CurrDDDriver].bIsPrimary ? NULL : &myglobs.DDDriver[myglobs.CurrDDDriver].Guid,
AfterDeviceCreated, NULL, BeforeDeviceDestroyed, NULL, &d3dapp)) {
ReportD3DAppError();
return FALSE;
}
#if 0
// DEBUG - helps with fullscreen exclusive debugs!
ShowWindow(myglobs.hWndMain, SW_HIDE);
#endif
/*
* Add the the list of display modes D3DApp found to the mode menu
*/
hmenu = GetSubMenu(GetMenu(myglobs.hWndMain), 4);
for (i = 0; i < d3dapp->NumModes; i++) {
char ach[80];
wsprintf(ach,"%dx%dx%d", d3dapp->Mode[i].w, d3dapp->Mode[i].h,
d3dapp->Mode[i].bpp);
if ((d3dapp->Mode[i].w == 640) && (d3dapp->Mode[i].h == 480) && (d3dapp->Mode[i].bpp == 16))
AppendMenu(hmenu, MF_STRING, MENU_FIRST_MODE+i, ach);
//else
//AppendMenu(hmenu, MF_STRING | MF_DISABLED | MF_GRAYED, MENU_FIRST_MODE+i, ach);
}
/*
* Add the list of D3D drivers D3DApp foudn to the file menu
*/
hmenu = GetSubMenu(GetMenu(myglobs.hWndMain), 0);
for (i = 0; i < d3dapp->NumDrivers; i++) {
if (strstr(myglobs.DDDriver[i].Name,"HAL") == NULL)
InsertMenu(hmenu, 7 + myglobs.NumDDDrivers + i, MF_BYPOSITION | MF_STRING | MF_GRAYED,
MENU_FIRST_DRIVER + i, d3dapp->Driver[i].Name);
else
InsertMenu(hmenu, 7 + myglobs.NumDDDrivers + i, MF_BYPOSITION | MF_STRING,
MENU_FIRST_DRIVER + i, d3dapp->Driver[i].Name);
}
/*
* Allow the sample to override the default render state and other
* settings
*/
if (!D3DAppGetRenderState(&defaults.rs)) {
ReportD3DAppError();
return FALSE;
}
lstrcpy(defaults.Name, "D3D Example");
defaults.bTexturesDisabled = FALSE;
defaults.bResizingDisabled = myglobs.bResizingDisabled;
defaults.bClearsOn = myglobs.bClearsOn;
OverrideDefaults(&defaults);
myglobs.bClearsOn = defaults.bClearsOn;
myglobs.bResizingDisabled = defaults.bResizingDisabled;
/*
* Apply any changes to the render state
*/
memcpy(&myglobs.rstate, &defaults.rs, sizeof(D3DAppRenderState));
if (!D3DAppSetRenderState(&myglobs.rstate)) {
ReportD3DAppError();
return FALSE;
}
/*
* If I should begin with textures off, disable them and re-create
* the view.
*/
if (defaults.bTexturesDisabled) {
if (!D3DAppDisableTextures(defaults.bTexturesDisabled)) {
ReportD3DAppError();
return FALSE;
}
/*
* Release all objects (ie execute buffers) created by InitView
*/
ReleaseView(d3dapp->lpD3DViewport);
/*
* Create the sample's execute buffers via InitView
*/
if (!InitView(d3dapp->lpDD, d3dapp->lpD3D, d3dapp->lpD3DDevice,
d3dapp->lpD3DViewport, d3dapp->NumUsableTextures,
d3dapp->TextureHandle)) {
Msg("InitView failed.\n");
CleanUpAndPostQuit();
return FALSE;
}
}
SetWindowText(myglobs.hWndMain, defaults.Name);
return TRUE;
}
/*
* DestroyD3DApp
*
* Destroy D3DApp and changes to menu
*/
static void
DestroyD3DApp(void)
{
HMENU hmenu;
int i;
/*
* Remove the list of display modes
*/
hmenu = GetSubMenu(GetMenu(myglobs.hWndMain), 4);
for (i = 0; i < d3dapp->NumModes; i++) {
DeleteMenu(hmenu, MENU_FIRST_MODE + i, MF_BYCOMMAND);
}
/*
* Remove the list of D3D drivers
*/
hmenu = GetSubMenu(GetMenu(myglobs.hWndMain), 0);
for (i = 0; i < d3dapp->NumDrivers; i++) {
DeleteMenu(hmenu, MENU_FIRST_DRIVER + i, MF_BYCOMMAND);
}
D3DAppDestroy();
}
/*
* AfterDeviceCreated
* D3DApp will call this function immediately after the D3D device has been
* created (or re-created). D3DApp expects the D3D viewport to be created and
* returned. The sample's execute buffers are also created (or re-created)
* here.
*/
static BOOL
AfterDeviceCreated(int w, int h, LPDIRECT3DVIEWPORT* lplpViewport, LPVOID lpContext)
{
HMENU hmenu;
int i;
char ach[20];
LPDIRECT3DVIEWPORT lpD3DViewport;
HRESULT rval;
/*
* Create the D3D viewport object
*/
rval = d3dapp->lpD3D->CreateViewport(&lpD3DViewport, NULL);
if (rval != D3D_OK) {
Msg("Create D3D viewport failed.\n%s", D3DAppErrorToString(rval));
CleanUpAndPostQuit();
return FALSE;
}
/*
* Add the viewport to the D3D device
*/
rval = d3dapp->lpD3DDevice->AddViewport(lpD3DViewport);
if (rval != D3D_OK) {
Msg("Add D3D viewport failed.\n%s", D3DAppErrorToString(rval));
CleanUpAndPostQuit();
return FALSE;
}
/*
* Setup the viewport for a reasonable viewing area
*/
D3DVIEWPORT viewData;
memset(&viewData, 0, sizeof(D3DVIEWPORT));
viewData.dwSize = sizeof(D3DVIEWPORT);
viewData.dwX = viewData.dwY = 0;
viewData.dwWidth = w;
viewData.dwHeight = h;
viewData.dvScaleX = viewData.dwWidth / (float)2.0;
viewData.dvScaleY = viewData.dwHeight / (float)2.0;
viewData.dvMaxX = (float)D3DDivide(D3DVAL(viewData.dwWidth),
D3DVAL(2 * viewData.dvScaleX));
viewData.dvMaxY = (float)D3DDivide(D3DVAL(viewData.dwHeight),
D3DVAL(2 * viewData.dvScaleY));
rval = lpD3DViewport->SetViewport(&viewData);
if (rval != D3D_OK) {
Msg("SetViewport failed.\n%s", D3DAppErrorToString(rval));
CleanUpAndPostQuit();
return FALSE;
}
/*
* Return the viewport to D3DApp so it can use it
*/
*lplpViewport = lpD3DViewport;
/*
* Create the sample's execute buffers via InitView
*/
if (!InitView(d3dapp->lpDD, d3dapp->lpD3D, d3dapp->lpD3DDevice,
lpD3DViewport, d3dapp->NumUsableTextures,
d3dapp->TextureHandle)) {
Msg("InitView failed.\n");
CleanUpAndPostQuit();
return FALSE;
}
/*
* Add the list of texture formats found by D3DApp to the texture menu
*/
hmenu = GetSubMenu(GetMenu(myglobs.hWndMain), 3);
for (i = 0; i < d3dapp->NumTextureFormats; i++) {
if (d3dapp->TextureFormat[i].bPalettized) {
wsprintf(ach, "%d-bit Palettized",
d3dapp->TextureFormat[i].IndexBPP);
} else {
wsprintf(ach, "%d%d%d RGB", d3dapp->TextureFormat[i].RedBPP,
d3dapp->TextureFormat[i].GreenBPP,
d3dapp->TextureFormat[i].BlueBPP);
}
AppendMenu(hmenu, MF_STRING, MENU_FIRST_FORMAT + i, ach);
}
/*
* Create and initialize the surfaces containing the frame rate and
* window information
*/
InitFontAndTextBuffers();
return TRUE;
}
/*
* BeforeDeviceDestroyed
* D3DApp will call this function before the current D3D device is destroyed
* to give the app the opportunity to destroy objects it has created with the
* DD or D3D objects.
*/
static BOOL
BeforeDeviceDestroyed(LPVOID lpContext)
{
HMENU hmenu;
int i;
/*
* Release the font object and buffers containing stats
*/
ReleaseFontAndTextBuffers();
if (d3dapp && d3dapp->lpD3DViewport) {
/*
* Release all objects (ie execute buffers) created by InitView
*/
ReleaseView(d3dapp->lpD3DViewport);
/*
* Since we created the viewport it is our responsibility to release
* it. Use D3DApp's pointer to it since we didn't save one.
*/
d3dapp->lpD3DViewport->Release();
d3dapp->lpD3DViewport = NULL;
}
/*
* Delete the list of texture formats from the texture menu because
* they are likely to change
*/
if (myglobs.hWndMain) {
hmenu = GetSubMenu(GetMenu(myglobs.hWndMain), 3);
if (hmenu) {
for (i = 0; i < d3dapp->NumTextureFormats; i++) {
DeleteMenu(hmenu, MENU_FIRST_FORMAT + i, MF_BYCOMMAND);
}
}
}
return TRUE;
}
/****************************************************************************/
/* Rendering loop */
/****************************************************************************/
/*
* RenderLoop
* Render the next frame and update the window
*/
static BOOL
RenderLoop()
{
D3DRECT extents[D3DAPP_MAXCLEARRECTS];
int count;
RECT dRect, sRect;
HRESULT ddrval;
/*
* If all the DD and D3D objects have been initialized we can render
*/
if (d3dapp->bRenderingIsOK) {
/*
* Restore any lost surfaces
*/
if (!RestoreSurfaces()) {
/*
* Restoring surfaces sometimes fails because the surfaces cannot
* yet be restored. If this is the case, the error will show up
* somewhere else and we should return success here to prevent
* unnecessary error's being reported.
*/
return TRUE;
}
/*
* Calculate the frame rate
*/
if (!CalculateFrameRate())
return FALSE;
/*
* Clear the back buffer and Z buffer if enabled. If bResized is set,
* clear the entire window.
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -