home *** CD-ROM | disk | FTP | other *** search
- /*
- * Copyright (C) 1995, 1996 Microsoft Corporation. All Rights Reserved.
- *
- * File: rmmain.cpp
- *
- * Each of the Direct3D retained mode (D3DRM) samples must be linked with
- * this file. It contains the code which allows them to run in the Windows
- * environment.
- *
- * A window is created using the rmmain.res which allows the user to select
- * the Direct3D driver to use and change the render options.
- *
- * Individual samples are executed through two functions, BuildScene and
- * OverrideDefaults, as described in rmdemo.h. Samples can also read
- * mouse input via ReadMouse.
- */
-
- #define INITGUID
-
- #include <windows.h>
- #include <stdio.h>
- #include <string.h>
- #include <malloc.h>
- #include <math.h>
- #include <direct.h>
- #include <d3drmwin.h>
- #include "rmdemo.h" /* prototypes for functions to commumicate
- with each sample */
- #include "rmmain.h" /* defines constants used in rmmain.rc */
- #include "rmerror.h" /* prototypes for error reporting: error.c */
-
- #define MAX_DRIVERS 5 /* maximum D3D drivers we ever expect to find */
-
- /*
- * GLOBAL VARIABLES
- */
- LPDIRECT3DRM lpD3DRM; /* Direct3DRM object */
- LPDIRECTDRAWCLIPPER lpDDClipper;/* DirectDrawClipper object */
-
- struct _myglobs {
- LPDIRECT3DRMDEVICE dev; /* Direct3DRM device */
- LPDIRECT3DRMVIEWPORT view; /* Direct3DRM viewport through which we view
- the scene */
- LPDIRECT3DRMFRAME scene; /* Master frame in which others are placed */
- LPDIRECT3DRMFRAME camera; /* Frame describing the users POV */
-
- GUID DriverGUID[MAX_DRIVERS]; /* GUIDs of the available D3D drivers */
- char DriverName[MAX_DRIVERS][50]; /* names of the available D3D drivers */
- int NumDrivers; /* number of available D3D drivers */
- int CurrDriver; /* number of D3D driver currently
- being used */
-
- D3DRMRENDERQUALITY RenderQuality; /* current shade mode, fill mode and
- lighting state */
- D3DRMTEXTUREQUALITY TextureQuality; /* current texture interpolation */
- BOOL bDithering; /* is dithering on? */
- BOOL bAntialiasing; /* is antialiasing on? */
-
- BOOL bQuit; /* program is about to terminate */
- BOOL bInitialized; /* all D3DRM objects have been initialized */
- BOOL bMinimized; /* window is minimized */
- BOOL bSingleStepMode; /* render one frame at a time */
- BOOL bDrawAFrame; /* render on this pass of the main loop */
- BOOL bNoTextures; /* this sample doesn't use any textures */
- BOOL bConstRenderQuality; /* this sample is not constructed with
- MeshBuilders and so the RenderQuality
- cannot be changed */
-
- int BPP; /* bit depth of the current display mode */
-
- int mouse_buttons; /* mouse button state */
- int mouse_x; /* mouse cursor x position */
- int mouse_y; /* mouse cursor y position */
- } myglobs;
-
- /*
- * PROTOTYPES
- */
- static BOOL InitApp(HINSTANCE, int);
- static void InitGlobals(void);
- long FAR PASCAL WindowProc(HWND, UINT, WPARAM, LPARAM);
- static BOOL CreateDevAndView(LPDIRECTDRAWCLIPPER lpDDClipper, int driver, int width, int height);
- static BOOL RenderLoop(void);
- static void CleanUpAndPostQuit(void);
- static BOOL SetRenderState(void);
- static BOOL EnumDrivers(HWND win);
- extern "C" void ReadMouse(int*, int*, int*);
-
- /****************************************************************************/
- /* WinMain */
- /****************************************************************************/
- /*
- * Initializes the application then enters a message loop which renders the
- * scene until a quit message is received.
- */
- int PASCAL
- WinMain (HINSTANCE this_inst, HINSTANCE prev_inst, LPSTR cmdline, int cmdshow)
- {
- MSG msg;
- HACCEL accel;
- int failcount = 0; /* number of times RenderLoop has failed */
-
- prev_inst;
- cmdline;
-
- /*
- * Create the window and initialize all objects needed to begin rendering
- */
- if (!InitApp(this_inst, cmdshow))
- return 1;
-
- accel = LoadAccelerators(this_inst, "AppAccel");
-
- while (!myglobs.bQuit) {
- /*
- * Monitor the message queue until there are no pressing
- * messages
- */
- while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
- if (msg.message == WM_QUIT) {
- CleanUpAndPostQuit();
- break;
- }
- if (!TranslateAccelerator(msg.hwnd, accel, &msg)) {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- }
- /*
- * If the app is not minimized, not about to quit and D3DRM has
- * been initialized, we can render
- */
- if (!myglobs.bMinimized && !myglobs.bQuit && myglobs.bInitialized) {
- /*
- * If were are not in single step mode or if we are and the
- * bDrawAFrame flag is set, render one frame
- */
- if (!(myglobs.bSingleStepMode && !myglobs.bDrawAFrame)) {
- /*
- * Attempt to render a frame, if it fails, take a note. If
- * rendering fails more than twice, abort execution.
- */
- if (!RenderLoop())
- ++failcount;
- if (failcount > 2) {
- Msg("Rendering has failed too many times. Aborting execution.\n");
- CleanUpAndPostQuit();
- break;
- }
- }
- /*
- * Reset the bDrawAFrame flag if we are in single step mode
- */
- if (myglobs.bSingleStepMode)
- myglobs.bDrawAFrame = FALSE;
- }
- }
- return msg.wParam;
- }
-
- /****************************************************************************/
- /* Initialization and object creation */
- /****************************************************************************/
- /*
- * InitApp
- * Creates window and initializes all objects neccessary to begin rendering
- */
- static BOOL
- InitApp(HINSTANCE this_inst, int cmdshow)
- {
- HWND win;
- HDC hdc;
- DWORD flags;
- WNDCLASS wc;
- Defaults defaults;
- HRESULT rval;
- RECT rc;
-
- /*
- * set up and registers the window class
- */
- wc.style = CS_HREDRAW | CS_VREDRAW;
- wc.lpfnWndProc = WindowProc;
- wc.cbClsExtra = 0;
- wc.cbWndExtra = sizeof(DWORD);
- wc.hInstance = this_inst;
- wc.hIcon = LoadIcon(this_inst, "AppIcon");
- wc.hCursor = LoadCursor(NULL, IDC_ARROW);
- wc.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH);
- wc.lpszMenuName = "AppMenu";
- wc.lpszClassName = "D3DRM Example";
- if (!RegisterClass(&wc))
- return FALSE;
- /*
- * Initialize the global variables and allow the sample code to override
- * some of these default settings.
- */
- InitGlobals();
- defaults.bNoTextures = myglobs.bNoTextures;
- defaults.bConstRenderQuality = myglobs.bConstRenderQuality;
- defaults.bResizingDisabled = FALSE;
- lstrcpy(defaults.Name, "D3DRM Example");
- OverrideDefaults(&defaults);
- myglobs.bNoTextures = defaults.bNoTextures;
- myglobs.bConstRenderQuality = defaults.bConstRenderQuality;
- /*
- * Create the window
- */
- if (defaults.bResizingDisabled)
- flags = WS_VISIBLE | WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU |
- WS_MINIMIZEBOX | WS_MAXIMIZEBOX;
- else
- flags = WS_OVERLAPPEDWINDOW;
- win =
- CreateWindow
- ( "D3DRM Example", /* class */
- defaults.Name, /* caption */
- flags, /* style */
- CW_USEDEFAULT, /* init. x pos */
- CW_USEDEFAULT, /* init. y pos */
- 300, /* init. x size */
- 300, /* init. y size */
- NULL, /* parent window */
- NULL, /* menu handle */
- this_inst, /* program handle */
- NULL /* create parms */
- );
- if (!win)
- return FALSE;
- /*
- * Record the current display BPP
- */
- hdc = GetDC(win);
- myglobs.BPP = GetDeviceCaps(hdc, BITSPIXEL);
- ReleaseDC(win, hdc);
- /*
- * Enumerate the D3D drivers and select one
- */
- if (!EnumDrivers(win))
- return FALSE;
- /*
- * Create the D3DRM object and the D3DRM window object
- */
- rval = Direct3DRMCreate(&lpD3DRM);
- if (rval != D3DRM_OK) {
- Msg("Failed to create Direct3DRM.\n%s", D3DRMErrorToString(rval));
- return FALSE;
- }
- /*
- * Create the master scene frame and camera frame
- */
- rval = lpD3DRM->CreateFrame(NULL, &myglobs.scene);
- if (rval != D3DRM_OK) {
- Msg("Failed to create the master scene frame.\n%s", D3DRMErrorToString(rval));
- return FALSE;
- }
- rval = lpD3DRM->CreateFrame(myglobs.scene, &myglobs.camera);
- if (rval != D3DRM_OK) {
- Msg("Failed to create the camera's frame.\n%s", D3DRMErrorToString(rval));
- return FALSE;
- }
- rval = myglobs.camera->SetPosition(myglobs.scene, D3DVAL(0.0), D3DVAL(0.0), D3DVAL(0.0));
- if (rval != D3DRM_OK) {
- Msg("Failed to position the camera in the frame.\n%s", D3DRMErrorToString(rval));
- return FALSE;
- }
- /*
- * Create a clipper and associate the window with it
- */
- rval = DirectDrawCreateClipper(0, &lpDDClipper, NULL);
- if (rval != DD_OK) {
- Msg("Failed to create DirectDrawClipper");
- return FALSE;
- }
- rval = lpDDClipper->SetHWnd(0, win);
- if (rval != DD_OK) {
- Msg("Failed to set hwnd on the clipper");
- return FALSE;
- }
- /*
- * Created the D3DRM device with the selected D3D driver
- */
- GetClientRect(win, &rc);
- if (!CreateDevAndView(lpDDClipper, myglobs.CurrDriver, rc.right, rc.bottom)) {
- return FALSE;
- }
- /*
- * Create the scene to be rendered by calling this sample's BuildScene
- */
- if (!BuildScene(myglobs.dev, myglobs.view, myglobs.scene, myglobs.camera))
- return FALSE;
- /*
- * Now we are ready to render
- */
- myglobs.bInitialized = TRUE;
- /*
- * Display the window
- */
- ShowWindow(win, cmdshow);
- UpdateWindow(win);
-
- return TRUE;
- }
-
- /*
- * CreateDevAndView
- * Create the D3DRM device and viewport with the given D3D driver and of the
- * specified size.
- */
- static BOOL
- CreateDevAndView(LPDIRECTDRAWCLIPPER lpDDClipper, int driver, int width, int height)
- {
- HRESULT rval;
-
- if (!width || !height) {
- Msg("Cannot create a D3DRM device with invalid window dimensions.");
- return FALSE;
- }
- /*
- * Create the D3DRM device from this window and using the specified D3D
- * driver.
- */
- rval = lpD3DRM->CreateDeviceFromClipper(lpDDClipper, &myglobs.DriverGUID[driver],
- width, height, &myglobs.dev);
- if (rval != D3DRM_OK) {
- Msg("Failed to create the D3DRM device from the clipper.\n%s",
- D3DRMErrorToString(rval));
- return FALSE;
- }
- /*
- * Create the D3DRM viewport using the camera frame. Set the background
- * depth to a large number. The width and height may be slightly
- * adjusted, so get them from the device to be sure.
- */
- width = myglobs.dev->GetWidth();
- height = myglobs.dev->GetHeight();
- rval = lpD3DRM->CreateViewport(myglobs.dev, myglobs.camera, 0, 0, width,
- height, &myglobs.view);
- if (rval != D3DRM_OK) {
- Msg("Failed to create the D3DRM viewport.\n%s",
- D3DRMErrorToString(rval));
- RELEASE(myglobs.dev);
- return FALSE;
- }
- rval = myglobs.view->SetBack(D3DVAL(5000.0));
- if (rval != D3DRM_OK) {
- Msg("Failed to set the background depth of the D3DRM viewport.\n%s",
- D3DRMErrorToString(rval));
- RELEASE(myglobs.dev);
- RELEASE(myglobs.view);
- return FALSE;
- }
- /*
- * Set the render quality, fill mode, lighting state and color shade info
- */
- if (!SetRenderState())
- return FALSE;
- return TRUE;
- }
-
- /****************************************************************************/
- /* D3D Device Enumeration */
- /****************************************************************************/
- /*
- * BPPToDDBD
- * Converts bits per pixel to a DirectDraw bit depth flag
- */
- static DWORD
- BPPToDDBD(int bpp)
- {
- switch(bpp) {
- case 1:
- return DDBD_1;
- case 2:
- return DDBD_2;
- case 4:
- return DDBD_4;
- case 8:
- return DDBD_8;
- case 16:
- return DDBD_16;
- case 24:
- return DDBD_24;
- case 32:
- return DDBD_32;
- default:
- return 0;
- }
- }
-
- /*
- * enumDeviceFunc
- * Callback function which records each usable D3D driver's name and GUID
- * Chooses a driver to begin with and sets *lpContext to this starting driver
- */
- static HRESULT
- WINAPI enumDeviceFunc(LPGUID lpGuid, LPSTR lpDeviceDescription, LPSTR lpDeviceName,
- LPD3DDEVICEDESC lpHWDesc, LPD3DDEVICEDESC lpHELDesc, LPVOID lpContext)
- {
- static BOOL hardware = FALSE; /* current start driver is hardware */
- static BOOL mono = FALSE; /* current start driver is mono light */
- LPD3DDEVICEDESC lpDesc;
- int *lpStartDriver = (int *)lpContext;
- /*
- * Decide which device description we should consult
- */
- lpDesc = lpHWDesc->dcmColorModel ? lpHWDesc : lpHELDesc;
- /*
- * If this driver cannot render in the current display bit depth skip
- * it and continue with the enumeration.
- */
- if (!(lpDesc->dwDeviceRenderBitDepth & BPPToDDBD(myglobs.BPP)))
- return D3DENUMRET_OK;
- /*
- * Record this driver's info
- */
- memcpy(&myglobs.DriverGUID[myglobs.NumDrivers], lpGuid, sizeof(GUID));
- lstrcpy(&myglobs.DriverName[myglobs.NumDrivers][0], lpDeviceName);
- /*
- * Choose hardware over software, RGB lights over mono lights
- */
- if (*lpStartDriver == -1) {
- /*
- * this is the first valid driver
- */
- *lpStartDriver = myglobs.NumDrivers;
- hardware = lpDesc == lpHWDesc ? TRUE : FALSE;
- mono = lpDesc->dcmColorModel & D3DCOLOR_MONO ? TRUE : FALSE;
- } else if (lpDesc == lpHWDesc && !hardware) {
- /*
- * this driver is hardware and start driver is not
- */
- *lpStartDriver = myglobs.NumDrivers;
- hardware = lpDesc == lpHWDesc ? TRUE : FALSE;
- mono = lpDesc->dcmColorModel & D3DCOLOR_MONO ? TRUE : FALSE;
- } else if ((lpDesc == lpHWDesc && hardware ) || (lpDesc == lpHELDesc
- && !hardware)) {
- if (lpDesc->dcmColorModel == D3DCOLOR_MONO && !mono) {
- /*
- * this driver and start driver are the same type and this
- * driver is mono while start driver is not
- */
- *lpStartDriver = myglobs.NumDrivers;
- hardware = lpDesc == lpHWDesc ? TRUE : FALSE;
- mono = lpDesc->dcmColorModel & D3DCOLOR_MONO ? TRUE : FALSE;
- }
- }
- myglobs.NumDrivers++;
- if (myglobs.NumDrivers == MAX_DRIVERS)
- return (D3DENUMRET_CANCEL);
- return (D3DENUMRET_OK);
- }
-
- /*
- * EnumDrivers
- * Enumerate the available D3D drivers, add them to the file menu, and choose
- * one to use.
- */
- static BOOL
- EnumDrivers(HWND win)
- {
- LPDIRECTDRAW lpDD;
- LPDIRECT3D lpD3D;
- HRESULT rval;
- HMENU hmenu;
- int i;
-
- /*
- * Create a DirectDraw object and query for the Direct3D interface to use
- * to enumerate the drivers.
- */
- rval = DirectDrawCreate(NULL, &lpDD, NULL);
- if (rval != DD_OK) {
- Msg("Creation of DirectDraw HEL failed.\n%s", D3DRMErrorToString(rval));
- return FALSE;
- }
- rval = lpDD->QueryInterface(IID_IDirect3D, (void**) &lpD3D);
- if (rval != DD_OK) {
- Msg("Creation of Direct3D interface failed.\n%s", D3DRMErrorToString(rval));
- lpDD->Release();
- return FALSE;
- }
- /*
- * Enumerate the drivers, setting CurrDriver to -1 to initialize the
- * driver selection code in enumDeviceFunc
- */
- myglobs.CurrDriver = -1;
- rval = lpD3D->EnumDevices(enumDeviceFunc, &myglobs.CurrDriver);
- if (rval != DD_OK) {
- Msg("Enumeration of drivers failed.\n%s", D3DRMErrorToString(rval));
- return FALSE;
- }
- /*
- * Make sure we found at least one valid driver
- */
- if (myglobs.NumDrivers == 0) {
- Msg("Could not find a D3D driver which is compatible with this display depth");
- return FALSE;
- }
- lpD3D->Release();
- lpDD->Release();
- /*
- * Add the driver names to the File menu
- */
- hmenu = GetSubMenu(GetMenu(win), 0);
- for (i = 0; i < myglobs.NumDrivers; i++) {
- InsertMenu(hmenu, 5 + i, MF_BYPOSITION | MF_STRING, MENU_FIRST_DRIVER + i,
- myglobs.DriverName[i]);
- }
- return TRUE;
- }
-
- /****************************************************************************/
- /* Render Loop */
- /****************************************************************************/
- /*
- * Clear the viewport, render the next frame and update the window
- */
- static BOOL
- RenderLoop()
- {
- HRESULT rval;
- /*
- * Tick the scene
- */
- rval = myglobs.scene->Move(D3DVAL(1.0));
- if (rval != D3DRM_OK) {
- Msg("Moving scene failed.\n%s", D3DRMErrorToString(rval));
- return FALSE;
- }
- /*
- * Clear the viewport
- */
- rval = myglobs.view->Clear();
- if (rval != D3DRM_OK) {
- Msg("Clearing viewport failed.\n%s", D3DRMErrorToString(rval));
- return FALSE;
- }
- /*
- * Render the scene to the viewport
- */
- rval = myglobs.view->Render(myglobs.scene);
- if (rval != D3DRM_OK) {
- Msg("Rendering scene failed.\n%s", D3DRMErrorToString(rval));
- return FALSE;
- }
- /*
- * Update the window
- */
- rval = myglobs.dev->Update();
- if (rval != D3DRM_OK) {
- Msg("Updating device failed.\n%s", D3DRMErrorToString(rval));
- return FALSE;
- }
- return TRUE;
- }
-
-
- /****************************************************************************/
- /* Windows Message Handlers */
- /****************************************************************************/
- /*
- * AppAbout
- * About box message handler
- */
- BOOL
- FAR PASCAL AppAbout(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lParam)
- {
- switch (msg)
- {
- case WM_COMMAND:
- if (LOWORD(wparam) == IDOK)
- EndDialog(hwnd, TRUE);
- break;
-
- case WM_INITDIALOG:
- return TRUE;
- }
- return FALSE;
- }
-
- /*
- * WindowProc
- * Main window message handler
- */
- LONG FAR PASCAL WindowProc(HWND win, UINT msg, WPARAM wparam, LPARAM lparam)
- {
- int i;
- HRESULT rval;
- RECT rc;
-
- switch (msg) {
- case WM_LBUTTONDOWN:
- case WM_LBUTTONUP:
- case WM_RBUTTONDOWN:
- case WM_RBUTTONUP:
- case WM_MOUSEMOVE:
- /*
- * Record the mouse state for ReadMouse
- */
- myglobs.mouse_buttons = wparam;
- myglobs.mouse_x = LOWORD(lparam);
- myglobs.mouse_y = HIWORD(lparam);
- break;
- case WM_INITMENUPOPUP:
- /*
- * Check and enable the appropriate menu items
- */
- CheckMenuItem((HMENU)wparam, MENU_STEP,(myglobs.bSingleStepMode) ? MF_CHECKED : MF_UNCHECKED);
- EnableMenuItem((HMENU)wparam, MENU_GO,(myglobs.bSingleStepMode) ? MF_ENABLED : MF_GRAYED);
- if (!myglobs.bConstRenderQuality) {
- CheckMenuItem((HMENU)wparam, MENU_LIGHTING, (myglobs.RenderQuality & D3DRMLIGHT_MASK) == D3DRMLIGHT_ON ? MF_CHECKED : MF_GRAYED);
- CheckMenuItem((HMENU)wparam, MENU_FLAT, (myglobs.RenderQuality & D3DRMSHADE_MASK) == D3DRMSHADE_FLAT ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem((HMENU)wparam, MENU_GOURAUD, (myglobs.RenderQuality & D3DRMSHADE_MASK) == D3DRMSHADE_GOURAUD ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem((HMENU)wparam, MENU_PHONG, (myglobs.RenderQuality & D3DRMSHADE_MASK) == D3DRMSHADE_PHONG ? MF_CHECKED : MF_UNCHECKED);
- EnableMenuItem((HMENU)wparam, MENU_PHONG, MF_GRAYED);
- CheckMenuItem((HMENU)wparam, MENU_POINT, (myglobs.RenderQuality & D3DRMFILL_MASK) == D3DRMFILL_POINTS ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem((HMENU)wparam, MENU_WIREFRAME, (myglobs.RenderQuality & D3DRMFILL_MASK) == D3DRMFILL_WIREFRAME ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem((HMENU)wparam, MENU_SOLID, (myglobs.RenderQuality & D3DRMFILL_MASK) == D3DRMFILL_SOLID ? MF_CHECKED : MF_UNCHECKED);
- } else {
- EnableMenuItem((HMENU)wparam, MENU_LIGHTING, MF_GRAYED);
- EnableMenuItem((HMENU)wparam, MENU_FLAT, MF_GRAYED);
- EnableMenuItem((HMENU)wparam, MENU_GOURAUD, MF_GRAYED);
- EnableMenuItem((HMENU)wparam, MENU_PHONG, MF_GRAYED);
- EnableMenuItem((HMENU)wparam, MENU_POINT, MF_GRAYED);
- EnableMenuItem((HMENU)wparam, MENU_WIREFRAME, MF_GRAYED);
- EnableMenuItem((HMENU)wparam, MENU_SOLID, MF_GRAYED);
- }
- if (!myglobs.bNoTextures) {
- CheckMenuItem((HMENU)wparam, MENU_POINT_FILTER, (myglobs.TextureQuality == D3DRMTEXTURE_NEAREST) ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem((HMENU)wparam, MENU_LINEAR_FILTER, (myglobs.TextureQuality == D3DRMTEXTURE_LINEAR) ? MF_CHECKED : MF_UNCHECKED);
- } else {
- EnableMenuItem((HMENU)wparam, MENU_POINT_FILTER, MF_GRAYED);
- EnableMenuItem((HMENU)wparam, MENU_LINEAR_FILTER, MF_GRAYED);
- }
- CheckMenuItem((HMENU)wparam, MENU_DITHERING, (myglobs.bDithering) ? MF_CHECKED : MF_UNCHECKED);
- CheckMenuItem((HMENU)wparam, MENU_ANTIALIAS, (myglobs.bAntialiasing) ? MF_CHECKED : MF_UNCHECKED);
- EnableMenuItem((HMENU)wparam, MENU_ANTIALIAS, MF_GRAYED);
- for (i = 0; i < myglobs.NumDrivers; i++) {
- CheckMenuItem((HMENU)wparam, MENU_FIRST_DRIVER + i,
- (i == myglobs.CurrDriver) ? MF_CHECKED : MF_UNCHECKED);
- }
- break;
- case WM_COMMAND:
- switch(LOWORD(wparam)) {
- case MENU_ABOUT:
- DialogBox((HINSTANCE)GetWindowLong(win, GWL_HINSTANCE),
- "AppAbout", win, (DLGPROC)AppAbout);
- break;
- case MENU_EXIT:
- CleanUpAndPostQuit();
- break;
- case MENU_STEP:
- /*
- * Begin single step more or draw a frame if in single
- * step mode
- */
- if (!myglobs.bSingleStepMode) {
- myglobs.bSingleStepMode = TRUE;
- myglobs.bDrawAFrame = TRUE;
- } else if (!myglobs.bDrawAFrame) {
- myglobs.bDrawAFrame = TRUE;
- }
- break;
- case MENU_GO:
- /*
- * Exit single step mode
- */
- myglobs.bSingleStepMode = FALSE;
- break;
- /*
- * Lighting toggle
- */
- case MENU_LIGHTING:
- myglobs.RenderQuality ^= D3DRMLIGHT_ON;
- SetRenderState();
- break;
- /*
- * Fill mode selection
- */
- case MENU_POINT:
- myglobs.RenderQuality = (myglobs.RenderQuality & ~D3DRMFILL_MASK) | D3DRMFILL_POINTS;
- SetRenderState();
- break;
- case MENU_WIREFRAME:
- myglobs.RenderQuality = (myglobs.RenderQuality & ~D3DRMFILL_MASK) | D3DRMFILL_WIREFRAME;
- SetRenderState();
- break;
- case MENU_SOLID:
- myglobs.RenderQuality = (myglobs.RenderQuality & ~D3DRMFILL_MASK) | D3DRMFILL_SOLID;
- SetRenderState();
- break;
- /*
- * Shade mode selection
- */
- case MENU_FLAT:
- myglobs.RenderQuality = (myglobs.RenderQuality & ~D3DRMSHADE_MASK) | D3DRMSHADE_FLAT;
- SetRenderState();
- break;
- case MENU_GOURAUD:
- myglobs.RenderQuality = (myglobs.RenderQuality & ~D3DRMSHADE_MASK) | D3DRMSHADE_GOURAUD;
- SetRenderState();
- break;
- case MENU_PHONG:
- myglobs.RenderQuality = (myglobs.RenderQuality & ~D3DRMSHADE_MASK) | D3DRMSHADE_PHONG;
- SetRenderState();
- break;
-
- case MENU_DITHERING:
- myglobs.bDithering = !myglobs.bDithering;
- SetRenderState();
- break;
- case MENU_ANTIALIAS:
- myglobs.bAntialiasing = !myglobs.bAntialiasing;
- break;
- /*
- * Texture filter selection
- */
- case MENU_POINT_FILTER:
- if (myglobs.TextureQuality == D3DRMTEXTURE_NEAREST)
- break;
- myglobs.TextureQuality = D3DRMTEXTURE_NEAREST;
- SetRenderState();
- break;
- case MENU_LINEAR_FILTER:
- if (myglobs.TextureQuality == D3DRMTEXTURE_LINEAR)
- break;
- myglobs.TextureQuality = D3DRMTEXTURE_LINEAR;
- SetRenderState();
- break;
- }
- /*
- * Changing the D3D Driver
- */
- if (LOWORD(wparam) >= MENU_FIRST_DRIVER &&
- LOWORD(wparam) < MENU_FIRST_DRIVER + MAX_DRIVERS &&
- myglobs.CurrDriver != LOWORD(wparam) - MENU_FIRST_DRIVER){
- /*
- * Release the current viewport and device and create
- * the new one
- */
- RELEASE(myglobs.view);
- RELEASE(myglobs.dev);
- myglobs.CurrDriver = LOWORD(wparam)-MENU_FIRST_DRIVER;
- GetClientRect(win, &rc);
- if (!CreateDevAndView(lpDDClipper, myglobs.CurrDriver,
- rc.right, rc.bottom)) {
- CleanUpAndPostQuit();
- }
- }
- /*
- * Draw a frame in single step mode after ever command
- */
- myglobs.bDrawAFrame = TRUE;
- break;
- case WM_DESTROY:
- CleanUpAndPostQuit();
- break;
- case WM_SIZE:
- /*
- * Handle resizing of the window
- */
- {
- int width = LOWORD(lparam);
- int height = HIWORD(lparam);
- if (width && height) {
- int view_width = myglobs.view->GetWidth();
- int view_height = myglobs.view->GetHeight();
- int dev_width = myglobs.dev->GetWidth();
- int dev_height = myglobs.dev->GetHeight();
- /*
- * If the window hasn't changed size and we aren't returning from
- * a minimize, there is nothing to do
- */
- if (view_width == width && view_height == height &&
- !myglobs.bMinimized)
- break;
- if (width <= dev_width && height <= dev_height) {
- /*
- * If the window has shrunk, we can use the same device with a
- * new viewport
- */
- RELEASE(myglobs.view);
- rval = lpD3DRM->CreateViewport(myglobs.dev, myglobs.camera,
- 0, 0, width, height,
- &myglobs.view);
- if (rval != D3DRM_OK) {
- Msg("Failed to resize the viewport.\n%s",
- D3DRMErrorToString(rval));
- CleanUpAndPostQuit();
- break;
- }
- rval = myglobs.view->SetBack(D3DVAL(5000.0));
- if (rval != D3DRM_OK) {
- Msg("Failed to set background depth after viewport resize.\n%s",
- D3DRMErrorToString(rval));
- CleanUpAndPostQuit();
- break;
- }
- } else {
- /*
- * If the window got larger than the current device, create a
- * new device.
- */
- RELEASE(myglobs.view);
- RELEASE(myglobs.dev);
- if (!CreateDevAndView(lpDDClipper, myglobs.CurrDriver, width,
- height)) {
- CleanUpAndPostQuit();
- break;
- }
- }
- /*
- * We must not longer be minimized
- */
- myglobs.bMinimized = FALSE;
- } else {
- /*
- * This is a minimize message
- */
- myglobs.bMinimized = TRUE;
- }
- }
- break;
- case WM_ACTIVATE:
- {
- /*
- * Create a Windows specific D3DRM window device to handle this
- * message
- */
- LPDIRECT3DRMWINDEVICE windev;
- if (!myglobs.dev)
- break;
- if (SUCCEEDED(myglobs.dev->QueryInterface(IID_IDirect3DRMWinDevice,
- (void **) &windev))) {
- if (FAILED(windev->HandleActivate(wparam)))
- Msg("Failed to handle WM_ACTIVATE.\n");
- windev->Release();
- } else {
- Msg("Failed to create Windows device to handle WM_ACTIVATE.\n");
- }
- }
- break;
- case WM_PAINT:
- if (!myglobs.bInitialized || !myglobs.dev)
- return DefWindowProc(win, msg, wparam, lparam);
- /*
- * Create a Windows specific D3DRM window device to handle this
- * message
- */
- RECT r;
- PAINTSTRUCT ps;
- LPDIRECT3DRMWINDEVICE windev;
-
- if (GetUpdateRect(win, &r, FALSE)) {
- BeginPaint(win, &ps);
- if (SUCCEEDED(myglobs.dev->QueryInterface(IID_IDirect3DRMWinDevice,
- (void **) &windev))) {
- if (FAILED(windev->HandlePaint(ps.hdc)))
- Msg("Failed to handle WM_PAINT.\n");
- windev->Release();
- } else {
- Msg("Failed to create Windows device to handle WM_PAINT.\n");
- }
- EndPaint(win, &ps);
- }
- break;
- default:
- return DefWindowProc(win, msg, wparam, lparam);
- }
- return 0L;
- }
-
- /*
- * SetRenderState
- * Set the render quality, dither toggle and shade info if any of them has
- * changed
- */
- BOOL
- SetRenderState(void)
- {
- HRESULT rval;
- /*
- * Set the render quality (light toggle, fill mode, shade mode)
- */
- if (myglobs.dev->GetQuality() != myglobs.RenderQuality) {
- rval = myglobs.dev->SetQuality(myglobs.RenderQuality);
- if (rval != D3DRM_OK) {
- Msg("Setting the render quality failed.\n%s",
- D3DRMErrorToString(rval));
- return FALSE;
- }
- }
- /*
- * Set dithering toggle
- */
- if (myglobs.dev->GetDither() != myglobs.bDithering) {
- rval = myglobs.dev->SetDither(myglobs.bDithering);
- if (rval != D3DRM_OK) {
- Msg("Setting dither mode failed.\n%s", D3DRMErrorToString(rval));
- return FALSE;
- }
- }
- /*
- * Set the texture quality (point or linear filtering)
- */
- if (myglobs.dev->GetTextureQuality() != myglobs.TextureQuality) {
- rval = myglobs.dev->SetTextureQuality(myglobs.TextureQuality);
- if (rval != D3DRM_OK) {
- Msg("Setting texture quality failed.\n%s",
- D3DRMErrorToString(rval));
- return FALSE;
- }
- }
- /*
- * Set shade info based on current bits per pixel
- */
- switch (myglobs.BPP) {
- case 1:
- if (FAILED(myglobs.dev->SetShades(4)))
- goto shades_error;
- if (FAILED(lpD3DRM->SetDefaultTextureShades(4)))
- goto shades_error;
- break;
- case 16:
- if (FAILED(myglobs.dev->SetShades(32)))
- goto shades_error;
- if (FAILED(lpD3DRM->SetDefaultTextureColors(64)))
- goto shades_error;
- if (FAILED(lpD3DRM->SetDefaultTextureShades(32)))
- goto shades_error;
- break;
- case 24:
- case 32:
- if (FAILED(myglobs.dev->SetShades(256)))
- goto shades_error;
- if (FAILED(lpD3DRM->SetDefaultTextureColors(64)))
- goto shades_error;
- if (FAILED(lpD3DRM->SetDefaultTextureShades(256)))
- goto shades_error;
- break;
- }
- return TRUE;
- shades_error:
- Msg("A failure occurred while setting color shade information.\n");
- return FALSE;
- }
-
- /****************************************************************************/
- /* Additional Functions */
- /****************************************************************************/
- /*
- * ReadMouse
- * Returns the mouse status for interaction with sample code
- */
- void
- ReadMouse(int* b, int* x, int* y)
- {
- *b = myglobs.mouse_buttons;
- *x = myglobs.mouse_x;
- *y = myglobs.mouse_y;
- }
-
- /*
- * InitGlobals
- * Initialize the global variables
- */
- void
- InitGlobals(void)
- {
- lpD3DRM = NULL;
- memset(&myglobs, 0, sizeof(myglobs));
- myglobs.RenderQuality = D3DRMLIGHT_ON | D3DRMFILL_SOLID |
- D3DRMSHADE_GOURAUD;
- myglobs.TextureQuality = D3DRMTEXTURE_NEAREST;
- }
-
- /*
- * CleanUpAndPostQuit
- * Release all D3DRM objects, post a quit message and set the bQuit flag
- */
- void
- CleanUpAndPostQuit(void)
- {
- myglobs.bInitialized = FALSE;
- RELEASE(myglobs.scene);
- RELEASE(myglobs.camera);
- RELEASE(myglobs.view);
- RELEASE(myglobs.dev);
- RELEASE(lpD3DRM);
- RELEASE(lpDDClipper);
- myglobs.bQuit = TRUE;
- }
-