home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
3D Graphics Programming for Windows 95
/
3D_Graphics_Programming_for_Windows_95_Microsoft_1996.iso
/
samples
/
blobs
/
mainfrm.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-17
|
10KB
|
423 lines
// MainFrm.cpp : implementation of the CMainFrame class
//
#include "stdafx.h"
#include "Stage.h"
#include "MainFrm.h"
#include "indevdlg.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CMainFrame
IMPLEMENT_DYNCREATE(CMainFrame, CFrameWnd)
BEGIN_MESSAGE_MAP(CMainFrame, CFrameWnd)
//{{AFX_MSG_MAP(CMainFrame)
ON_WM_CREATE()
ON_WM_DESTROY()
ON_WM_ACTIVATEAPP()
ON_WM_PALETTECHANGED()
ON_WM_MOVE()
ON_COMMAND(ID_FILE_NEW, OnFileNew)
ON_WM_SETFOCUS()
ON_COMMAND(ID_EDIT_CONTROL, OnEditControl)
ON_UPDATE_COMMAND_UI(ID_EDIT_CONTROL, OnUpdateEditControl)
ON_COMMAND(ID_EDIT_INPUTDEV, OnEditInputdev)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
static UINT indicators[] =
{
ID_SEPARATOR, // status line indicator
ID_INDICATOR_CAPS,
ID_INDICATOR_NUM,
ID_INDICATOR_SCRL,
};
/////////////////////////////////////////////////////////////////////////////
// CMainFrame construction/destruction
CMainFrame::CMainFrame()
{
m_pScene = NULL;
m_pCurShape = FALSE;
m_pController = NULL;
m_iObjCtrlDev = 0;
m_iControlObj = 0;
m_iControlType = 0;
}
CMainFrame::~CMainFrame()
{
}
int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CFrameWnd::OnCreate(lpCreateStruct) == -1)
return -1;
if (!m_wndToolBar.Create(this) ||
!m_wndToolBar.LoadToolBar(IDR_MAINFRAME))
{
TRACE0("Failed to create toolbar\n");
return -1; // fail to create
}
if (!m_wndStatusBar.Create(this) ||
!m_wndStatusBar.SetIndicators(indicators,
sizeof(indicators)/sizeof(UINT)))
{
TRACE0("Failed to create status bar\n");
return -1; // fail to create
}
// Create the 3D window
if (!m_wnd3d.Create(this, IDC_3DWND)) {
return -1;
}
// TODO: Remove this if you don't want tool tips or a resizeable toolbar
m_wndToolBar.SetBarStyle(m_wndToolBar.GetBarStyle() |
CBRS_TOOLTIPS | CBRS_FLYBY | CBRS_SIZE_DYNAMIC);
// TODO: Delete these three lines if you don't want the toolbar to
// be dockable
m_wndToolBar.EnableDocking(CBRS_ALIGN_ANY);
EnableDocking(CBRS_ALIGN_ANY);
DockControlBar(&m_wndToolBar);
NewScene();
ASSERT(m_pScene);
// Create the controller object
if (m_iControlType == 0) {
m_pController = new C3dPosCtlr;
} else {
m_pController = new C3dFlyCtlr;
}
m_pController->Create(&m_wnd3d,
OnGetCtrlFrame,
this);
// restore the controller settings
m_pController->SelectDevice(m_iObjCtrlDev);
// enable mouse selection of objects
m_wnd3d.EnableMouseSelection(OnSelChange, this);
return 0;
}
BOOL CMainFrame::PreCreateWindow(CREATESTRUCT& cs)
{
// Restore any saved settings
RestoreSettings();
// Restore the window size and position
cs.x = m_rcWnd.left;
cs.y = m_rcWnd.top;
cs.cx = m_rcWnd.Width();
cs.cy = m_rcWnd.Height();
return CFrameWnd::PreCreateWindow(cs);
}
BOOL CMainFrame::NewScene()
{
// Delete any scene we might have
if (m_pScene) {
m_wnd3d.SetScene(NULL);
delete m_pScene;
m_pScene = NULL;
}
// Create an initial scene
m_pScene = new C3dScene;
if (!m_pScene->Create()) return FALSE;
// Create a shape to add
m_pCurShape = new C3dShape;
m_pCurShape->CreateSphere(0.5, 4);
m_pScene->AddChild(m_pCurShape);
m_pScene->m_ShapeList.Append(m_pCurShape);
// Set up the lighting
C3dDirLight dl;
dl.Create(0.8, 0.8, 0.8);
m_pScene->AddChild(&dl);
dl.SetPosition(-2, 2, -5);
dl.SetDirection(1, -1, 1);
m_pScene->SetAmbientLight(0.4, 0.4, 0.4);
// reset the camera position and direction
m_pScene->SetCameraPosition(C3dVector(0, 0, -10));
m_pScene->SetCameraDirection(C3dVector(0, 0, 1), C3dVector(0, 1, 0));
m_wnd3d.SetScene(m_pScene);
return TRUE;
}
/////////////////////////////////////////////////////////////////////////////
// CMainFrame diagnostics
#ifdef _DEBUG
void CMainFrame::AssertValid() const
{
CFrameWnd::AssertValid();
}
void CMainFrame::Dump(CDumpContext& dc) const
{
CFrameWnd::Dump(dc);
}
#endif //_DEBUG
void CMainFrame::OnDestroy()
{
CFrameWnd::OnDestroy();
// Save the current settings
SaveSettings();
// destroy the controller
if (m_pController) {
delete m_pController;
m_pController = NULL;
}
// Delete any scene we might have
m_wnd3d.SetScene(NULL);
if (m_pScene) {
delete m_pScene;
m_pScene = NULL;
}
}
/////////////////////////////////////////////////////////////////////////////
// window layout handler
void CMainFrame::RecalcLayout(BOOL bNotify)
{
// Rearrange the control bars and fit the 3D window in the middle
// Let the frame rearrange the control bars
CFrameWnd::RecalcLayout(bNotify);
// Find the space that's left over
CRect rc;
RepositionBars(0,
0xFFFF,
IDC_3DWND,
CWnd::reposQuery,
&rc);
if (IsWindow(m_wnd3d.GetSafeHwnd())) {
m_wnd3d.MoveWindow(&rc, FALSE);
}
}
///////////////////////////////////////////////////////////////
// Windows messages we need to handle
void CMainFrame::OnActivateApp(BOOL bActive, HTASK hTask)
{
CFrameWnd::OnActivateApp(bActive, hTask);
// Tell the 3D window about the new state
m_wnd3d.SendMessage(WM_ACTIVATEAPP,
(WPARAM)bActive,
(LPARAM)hTask);
}
void CMainFrame::OnPaletteChanged(CWnd* pFocusWnd)
{
// Let the 3D window know
m_wnd3d.SendMessage(WM_PALETTECHANGED,
pFocusWnd ? (WPARAM)pFocusWnd->GetSafeHwnd() : 0);
}
void CMainFrame::OnMove(int x, int y)
{
CFrameWnd::OnMove(x, y);
// Let the 3D window know the frame has moved
m_wnd3d.SendMessage(WM_MOVE, 0, MAKELPARAM(0, 0));
}
void CMainFrame::OnSetFocus(CWnd* pOldWnd)
{
CFrameWnd::OnSetFocus(pOldWnd);
// Give the focus to the 3D window so it can process
// keystrokes for the key input device
m_wnd3d.SetFocus();
}
///////////////////////////////////////////////////////////////
// Adding new objects
void CMainFrame::OnFileNew()
{
NewScene();
}
BOOL CMainFrame::OpenFile(const char* pszPath)
{
return FALSE;
}
///////////////////////////////////////////////////////////////
// Format a string for the status bar
void CMainFrame::Status(const char* pszFormat, ...)
{
char buf[256];
va_list arglist;
va_start(arglist, pszFormat);
vsprintf(buf, pszFormat, arglist);
va_end(arglist);
m_wndStatusBar.SetWindowText(buf);
m_wndStatusBar.UpdateWindow();
}
//////////////////////////////////////////////////////////////
// Control device selection
// callback from the dialog to get a frame to control
// static
C3dFrame* CMainFrame::OnGetCtrlFrame(void* pArg)
{
CMainFrame* pThis = (CMainFrame*) pArg;
ASSERT(pThis);
ASSERT(pThis->IsKindOf(RUNTIME_CLASS(CMainFrame)));
if (pThis->m_iControlObj == 1) {
return pThis->m_wnd3d.GetCamera();
}
return pThis->m_pCurShape;
}
void CMainFrame::OnEditControl()
{
CInpDevDlg dlg;
dlg.m_iObject = m_iControlObj;
dlg.m_iType = m_iControlType;
dlg.m_iDevice = m_iObjCtrlDev;
if (dlg.DoModal() != IDOK) return;
m_iControlObj = dlg.m_iObject;
// set up the controller type
if (dlg.m_iType != m_iControlType) {
if (m_pController) delete m_pController;
// create a new controller
m_iControlType = dlg.m_iType;
if (m_iControlType == 0) {
m_pController = new C3dPosCtlr;
} else {
m_pController = new C3dFlyCtlr;
}
m_pController->Create(&m_wnd3d,
OnGetCtrlFrame,
this);
}
ASSERT(m_pController);
m_pController->SelectDevice(dlg.m_iDevice);
m_iObjCtrlDev = m_pController->GetCurDevice();
Status("Control is now via: %s",
m_pController->GetDeviceName(m_iObjCtrlDev));
}
void CMainFrame::OnUpdateEditControl(CCmdUI* pCmdUI)
{
pCmdUI->Enable(m_pController ? TRUE : FALSE);
}
void CMainFrame::OnEditInputdev()
{
ASSERT(m_pController);
C3dInputDevice* pDev = m_pController->GetInputDevice();
ASSERT(pDev);
pDev->ShowConfigDlg();
}
//////////////////////////////////////////////////////////////////
// Save and Restore Settings
void CMainFrame::SaveSettings()
{
CWinApp* pa = AfxGetApp();
pa->WriteProfileInt("Settings","ControlDevice", m_iObjCtrlDev);
CRect rc;
GetWindowRect(&rc);
pa->WriteProfileInt("Settings\\Window","Top", rc.top);
pa->WriteProfileInt("Settings\\Window","Left", rc.left);
pa->WriteProfileInt("Settings\\Window","Width", rc.Width());
pa->WriteProfileInt("Settings\\Window","Height", rc.Height());
}
void CMainFrame::RestoreSettings()
{
CWinApp* pa = AfxGetApp();
m_iObjCtrlDev = pa->GetProfileInt("Settings","ControlDevice", 0);
m_rcWnd.top = pa->GetProfileInt("Settings\\Window","Top", 50);
m_rcWnd.left = pa->GetProfileInt("Settings\\Window","Left", 50);
m_rcWnd.right = m_rcWnd.left + pa->GetProfileInt("Settings\\Window","Width", 300);
m_rcWnd.bottom = m_rcWnd.top + pa->GetProfileInt("Settings\\Window","Height", 350);
}
//////////////////////////////////////////////////////////////////////////
// object selection
// callback notification function
// called by m_wnd3d when the object selection changes
// static
void CMainFrame::OnSelChange(C3dShape* pShape, CPoint pt,
void* pArg)
{
// Get pointer to the class
CMainFrame* pThis = (CMainFrame*) pArg;
ASSERT(pThis);
ASSERT(pThis->IsKindOf(RUNTIME_CLASS(CMainFrame)));
if (pShape) {
// Find which face was hit
C3dViewport* pViewport = pThis->m_wnd3d.GetStage()->GetViewport();
int iFace;
C3dVector vHit;
if (pShape->HitTest(pt, pViewport, &iFace, &vHit)) {
pThis->AddBlob(pShape, vHit);
}
}
}
void CMainFrame::AddBlob(C3dShape* pShape, C3dVector& vHit)
{
// Get hit point on shape and
// convert from local to world coordinates
ASSERT(pShape);
C3dVector vh = pShape->Transform(vHit);
// Create a blob to add
C3dShape* pBlob = new C3dShape;
pBlob->CreateSphere(0.5, 4);
// Center it on hit point
pBlob->SetPosition(vh);
// Attach it to shape
pShape->AddChild(pBlob);
// Keep track of new blob so we can hit test it
m_pScene->m_ShapeList.Append(pBlob);
}