Click here to Skip to main content
15,896,348 members
Articles / Desktop Programming / MFC

Miner3D_viewer ActiveX control (for Miner3D game)

Rate me:
Please Sign up or sign in to vote.
4.33/5 (6 votes)
25 Feb 2004CPOL3 min read 72.3K   4.5K   24  
A solution for writing game 3D using VC combined with VB.
// Miner3D_viewerCtl.cpp : Implementation of the CMiner3D_viewerCtrl ActiveX Control class.

#include "stdafx.h"
#include "Miner3D_viewer.h"
#include "Miner3D_viewerCtl.h"
#include "Miner3D_viewerPpg.h"
#include <Mmsystem.h>
#include "PlayMidi.h"
#include <math.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif


IMPLEMENT_DYNCREATE(CMiner3D_viewerCtrl, COleControl)


/////////////////////////////////////////////////////////////////////////////
// Message map

BEGIN_MESSAGE_MAP(CMiner3D_viewerCtrl, COleControl)
	//{{AFX_MSG_MAP(CMiner3D_viewerCtrl)
	ON_WM_CREATE()
	ON_WM_DESTROY()
	ON_WM_TIMER()
	ON_WM_SIZE()
	ON_WM_PAINT()
	ON_WM_LBUTTONDOWN()
	ON_WM_RBUTTONDOWN()
	//}}AFX_MSG_MAP
	ON_MESSAGE(OCM_COMMAND, OnOcmCommand)
	ON_MESSAGE(MM_MCINOTIFY, OnMciNotify)
	ON_OLEVERB(AFX_IDS_VERB_PROPERTIES, OnProperties)
END_MESSAGE_MAP()


/////////////////////////////////////////////////////////////////////////////
// Dispatch map

BEGIN_DISPATCH_MAP(CMiner3D_viewerCtrl, COleControl)
	//{{AFX_DISPATCH_MAP(CMiner3D_viewerCtrl)
	DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "Interval", m_interval, OnIntervalChanged, VT_I4)
	DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "CharRotateDegree", m_charRotateDegree, OnCharRotateDegreeChanged, VT_R8)
	DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "SeeAngle", m_seeAngle, OnSeeAngleChanged, VT_R8)
	DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "SeeNearest", m_seeNearest, OnSeeNearestChanged, VT_R8)
	DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "SeeFarthest", m_seeFarthest, OnSeeFarthestChanged, VT_R8)
	DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "FogColor", m_fogColor, OnFogColorChanged, VT_COLOR)
	DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "FogDensity", m_fogDensity, OnFogDensityChanged, VT_R4)
	DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "PickLessExact", m_pickLessExact, OnPickLessExactChanged, VT_R8)
	DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "CamPosX", m_camPosX, OnCamPosXChanged, VT_R8)
	DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "CamPosY", m_camPosY, OnCamPosYChanged, VT_R8)
	DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "CamPosZ", m_camPosZ, OnCamPosZChanged, VT_R8)
	DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "CamAxz", m_camAxz, OnCamAxzChanged, VT_R8)
	DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "CamAzy", m_camAzy, OnCamAzyChanged, VT_R8)
	DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "Light1", m_light1, OnLight1Changed, VT_BOOL)
	DISP_PROPERTY_NOTIFY(CMiner3D_viewerCtrl, "WireVisible", m_wireVisible, OnWireVisibleChanged, VT_BOOL)
	DISP_FUNCTION(CMiner3D_viewerCtrl, "ClearAll", ClearAll, VT_EMPTY, VTS_NONE)
	DISP_FUNCTION(CMiner3D_viewerCtrl, "AddTile", AddTile, VT_BOOL, VTS_I4 VTS_R8 VTS_R8 VTS_R8)
	DISP_FUNCTION(CMiner3D_viewerCtrl, "AddChar", AddChar, VT_BOOL, VTS_I2 VTS_R8 VTS_R8 VTS_R8)
	DISP_FUNCTION(CMiner3D_viewerCtrl, "OpenTile", OpenTile, VT_EMPTY, VTS_I4)
	DISP_FUNCTION(CMiner3D_viewerCtrl, "ChangeTileColor", ChangeTileColor, VT_EMPTY, VTS_I4 VTS_COLOR)
	DISP_FUNCTION(CMiner3D_viewerCtrl, "AddColorTile", AddColorTile, VT_BOOL, VTS_I4 VTS_R8 VTS_R8 VTS_R8 VTS_COLOR)
	DISP_FUNCTION(CMiner3D_viewerCtrl, "Pick", Pick, VT_I4, VTS_R8 VTS_R8 VTS_PBOOL)
	DISP_FUNCTION(CMiner3D_viewerCtrl, "PlayMidiFile", PlayMidiFile, VT_EMPTY, VTS_BSTR)
	DISP_FUNCTION(CMiner3D_viewerCtrl, "StopPlayMidi", StopPlayMidi, VT_EMPTY, VTS_NONE)
	DISP_FUNCTION(CMiner3D_viewerCtrl, "GetCamDirX", GetCamDirX, VT_R8, VTS_NONE)
	DISP_FUNCTION(CMiner3D_viewerCtrl, "GetCamDirY", GetCamDirY, VT_R8, VTS_NONE)
	DISP_FUNCTION(CMiner3D_viewerCtrl, "GetCamDirZ", GetCamDirZ, VT_R8, VTS_NONE)
	DISP_FUNCTION(CMiner3D_viewerCtrl, "AddPoint", AddPoint, VT_BOOL, VTS_R8 VTS_R8 VTS_R8)
	DISP_FUNCTION(CMiner3D_viewerCtrl, "AddFace", AddFace, VT_BOOL, VTS_I2 VTS_R8 VTS_R8 VTS_R8 VTS_R8 VTS_COLOR)
	DISP_FUNCTION(CMiner3D_viewerCtrl, "GetTilePos", GetTilePos, VT_BOOL, VTS_I2 VTS_PR8 VTS_PR8 VTS_PR8)
	DISP_FUNCTION(CMiner3D_viewerCtrl, "AddWireTile", AddWireTile, VT_BOOL, VTS_R8 VTS_R8 VTS_R8)
	DISP_FUNCTION(CMiner3D_viewerCtrl, "AddColorWireTile", AddColorWireTile, VT_BOOL, VTS_R8 VTS_R8 VTS_R8 VTS_COLOR)
	DISP_FUNCTION(CMiner3D_viewerCtrl, "GetHandleActiveWindow", GetHandleActiveWindow, VT_HANDLE, VTS_NONE)
	DISP_DEFVALUE(CMiner3D_viewerCtrl, "BackColor")
	DISP_STOCKPROP_BACKCOLOR()
	DISP_FUNCTION_ID(CMiner3D_viewerCtrl, "Refresh", DISPID_REFRESH, Refresh, VT_EMPTY, VTS_NONE)
	//}}AFX_DISPATCH_MAP
	DISP_FUNCTION_ID(CMiner3D_viewerCtrl, "AboutBox", DISPID_ABOUTBOX, AboutBox, VT_EMPTY, VTS_NONE)
END_DISPATCH_MAP()


/////////////////////////////////////////////////////////////////////////////
// Event map

BEGIN_EVENT_MAP(CMiner3D_viewerCtrl, COleControl)
	//{{AFX_EVENT_MAP(CMiner3D_viewerCtrl)
	EVENT_CUSTOM("Timer", FireTimer, VTS_NONE)
	EVENT_CUSTOM("LeftButtonDown", FireLeftButtonDown, VTS_I4  VTS_I4  VTS_BOOL  VTS_BOOL)
	EVENT_CUSTOM("RightButtonDown", FireRightButtonDown, VTS_I4  VTS_I4  VTS_BOOL  VTS_BOOL)
	EVENT_CUSTOM("EndPlayMidi", FireEndPlayMidi, VTS_NONE)
	EVENT_CUSTOM("VcKeyDown", FireVcKeyDown, VTS_I4  VTS_I2)
	EVENT_CUSTOM("VcKeyUp", FireVcKeyUp, VTS_I4  VTS_I2)
	EVENT_STOCK_KEYDOWN()
	EVENT_STOCK_KEYUP()
	EVENT_STOCK_MOUSEDOWN()
	EVENT_STOCK_MOUSEUP()
	EVENT_STOCK_MOUSEMOVE()
	EVENT_STOCK_DBLCLICK()
	//}}AFX_EVENT_MAP
END_EVENT_MAP()


/////////////////////////////////////////////////////////////////////////////
// Property pages

// TODO: Add more property pages as needed.  Remember to increase the count!
BEGIN_PROPPAGEIDS(CMiner3D_viewerCtrl, 1)
	PROPPAGEID(CMiner3D_viewerPropPage::guid)
END_PROPPAGEIDS(CMiner3D_viewerCtrl)


/////////////////////////////////////////////////////////////////////////////
// Initialize class factory and guid

IMPLEMENT_OLECREATE_EX(CMiner3D_viewerCtrl, "MINER3DVIEWER.Miner3DviewerCtrl.1",
	0xe5a0ff08, 0x1c29, 0x11d8, 0xb8, 0x18, 0, 0x6, 0x7b, 0x2, 0xba, 0x6f)


/////////////////////////////////////////////////////////////////////////////
// Type library ID and version

IMPLEMENT_OLETYPELIB(CMiner3D_viewerCtrl, _tlid, _wVerMajor, _wVerMinor)


/////////////////////////////////////////////////////////////////////////////
// Interface IDs

const IID BASED_CODE IID_DMiner3D_viewer =
		{ 0xe5a0ff06, 0x1c29, 0x11d8, { 0xb8, 0x18, 0, 0x6, 0x7b, 0x2, 0xba, 0x6f } };
const IID BASED_CODE IID_DMiner3D_viewerEvents =
		{ 0xe5a0ff07, 0x1c29, 0x11d8, { 0xb8, 0x18, 0, 0x6, 0x7b, 0x2, 0xba, 0x6f } };


/////////////////////////////////////////////////////////////////////////////
// Control type information

static const DWORD BASED_CODE _dwMiner3D_viewerOleMisc =
	OLEMISC_ACTIVATEWHENVISIBLE |
	OLEMISC_SETCLIENTSITEFIRST |
	OLEMISC_INSIDEOUT |
	OLEMISC_CANTLINKINSIDE |
	OLEMISC_RECOMPOSEONRESIZE;

IMPLEMENT_OLECTLTYPE(CMiner3D_viewerCtrl, IDS_MINER3D_VIEWER, _dwMiner3D_viewerOleMisc)


/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::CMiner3D_viewerCtrlFactory::UpdateRegistry -
// Adds or removes system registry entries for CMiner3D_viewerCtrl

BOOL CMiner3D_viewerCtrl::CMiner3D_viewerCtrlFactory::UpdateRegistry(BOOL bRegister)
{
	// TODO: Verify that your control follows apartment-model threading rules.
	// Refer to MFC TechNote 64 for more information.
	// If your control does not conform to the apartment-model rules, then
	// you must modify the code below, changing the 6th parameter from
	// afxRegApartmentThreading to 0.

	if (bRegister)
		return AfxOleRegisterControlClass(
			AfxGetInstanceHandle(),
			m_clsid,
			m_lpszProgID,
			IDS_MINER3D_VIEWER,
			IDB_MINER3D_VIEWER,
			afxRegApartmentThreading,
			_dwMiner3D_viewerOleMisc,
			_tlid,
			_wVerMajor,
			_wVerMinor);
	else
		return AfxOleUnregisterClass(m_clsid, m_lpszProgID);
}


/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::CMiner3D_viewerCtrl - Constructor

CMiner3D_viewerCtrl::CMiner3D_viewerCtrl()
{
	InitializeIIDs(&IID_DMiner3D_viewer, &IID_DMiner3D_viewerEvents);

	// TODO: Initialize your control's instance data here.

}


/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::~CMiner3D_viewerCtrl - Destructor

CMiner3D_viewerCtrl::~CMiner3D_viewerCtrl()
{
	// TODO: Cleanup your control's instance data here.
}


/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::OnDraw - Drawing function

void CMiner3D_viewerCtrl::OnDraw(
			CDC* pdc, const CRect& rcBounds, const CRect& rcInvalid)
{
	DoSuperclassPaint(pdc, rcBounds);
}


/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::DoPropExchange - Persistence support

void CMiner3D_viewerCtrl::DoPropExchange(CPropExchange* pPX)
{
	ExchangeVersion(pPX, MAKELONG(_wVerMinor, _wVerMajor));
	COleControl::DoPropExchange(pPX);

	// TODO: Call PX_ functions for each persistent custom property.
	PX_Long(pPX,"Interval",m_interval,0);
	PX_Double(pPX,"CharRotateDegree",m_charRotateDegree,0);
	PX_Double(pPX,"SeeAngle",m_seeAngle,45.0);
	PX_Double(pPX,"SeeNearest",m_seeNearest,1.0);
	PX_Double(pPX,"SeeFarthest",m_seeFarthest,25.0);

	PX_Double(pPX,"CamPosX",m_camPosX,0.0);
	PX_Double(pPX,"CamPosY",m_camPosY,0.0);
	PX_Double(pPX,"CamPosZ",m_camPosZ,-8.0);
	PX_Double(pPX,"CamAxz",m_camAxz,3.1415/2);
	PX_Double(pPX,"CamAzy",m_camAzy,0.0);

	PX_Double(pPX,"PickLessExact",m_pickLessExact,5.0);
	
	PX_Color(pPX,"FogColor",m_fogColor,0x00808080);
	PX_Float(pPX,"FogDensity",m_fogDensity,0);

	PX_Bool(pPX,"Light1",m_light1,TRUE);
	PX_Bool(pPX,"WireVisible",m_wireVisible,TRUE);
}


/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::GetControlFlags -
// Flags to customize MFC's implementation of ActiveX controls.
//
// For information on using these flags, please see MFC technical note
// #nnn, "Optimizing an ActiveX Control".
DWORD CMiner3D_viewerCtrl::GetControlFlags()
{
	DWORD dwFlags = COleControl::GetControlFlags();


	// The control will not be redrawn when making the transition
	// between the active and inactivate state.
	dwFlags |= noFlickerActivate;
	return dwFlags;
}


/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::OnResetState - Reset control to default state

void CMiner3D_viewerCtrl::OnResetState()
{
	COleControl::OnResetState();  // Resets defaults found in DoPropExchange

	// TODO: Reset any other control state here.
}


/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::AboutBox - Display an "About" box to the user

void CMiner3D_viewerCtrl::AboutBox()
{
	CDialog dlgAbout(IDD_ABOUTBOX_MINER3D_VIEWER);
	dlgAbout.DoModal();
}


/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::PreCreateWindow - Modify parameters for CreateWindowEx

BOOL CMiner3D_viewerCtrl::PreCreateWindow(CREATESTRUCT& cs)
{
	//cs.lpszClass = _T("STATIC");
	return COleControl::PreCreateWindow(cs);
}


/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::IsSubclassedControl - This is a subclassed control

BOOL CMiner3D_viewerCtrl::IsSubclassedControl()
{
	return TRUE;
}


/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl::OnOcmCommand - Handle command messages

LRESULT CMiner3D_viewerCtrl::OnOcmCommand(WPARAM wParam, LPARAM lParam)
{
#ifdef _WIN32
	WORD wNotifyCode = HIWORD(wParam);
#else
	WORD wNotifyCode = HIWORD(lParam);
#endif

	// TODO: Switch on wNotifyCode here.

	return 0;
}


/////////////////////////////////////////////////////////////////////////////
// CMiner3D_viewerCtrl message handlers

int CMiner3D_viewerCtrl::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
	if (COleControl::OnCreate(lpCreateStruct) == -1)
		return -1;
	
	// TODO: Add your specialized creation code here

	hRC=SetUpOpenGL(m_hWnd);
	m_cc.Init(m_hWnd,hRC);

	m_tc.Add(1,0,0,0);
	
	UpdateCamDir();
	
	if (m_interval) SetTimer(1000,m_interval,NULL);
	m_cc.rotate=m_charRotateDegree;

	return 0;
}

void CMiner3D_viewerCtrl::OnDestroy() 
{
	COleControl::OnDestroy();
	
	// TODO: Add your message handler code here
	KillTimer(1000);
	
}

void CMiner3D_viewerCtrl::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	if(nIDEvent==1000)
	{
		FireTimer();
		RedrawWindow();
	}
	
	COleControl::OnTimer(nIDEvent);
}

void CMiner3D_viewerCtrl::OnSize(UINT nType, int cx, int cy) 
{
	COleControl::OnSize(nType, cx, cy);
	
	// TODO: Add your message handler code here
	HDC hDC = ::GetDC(this->m_hWnd);
	wglMakeCurrent(hDC,hRC);

	//**Write code for GL resize here!
    m_intWidth = (GLsizei)cx;
    m_intHeight = (GLsizei)cy;
    m_dblAspect = (GLdouble)m_intWidth/(GLdouble)m_intHeight;
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glViewport(0,0,m_intWidth,m_intHeight);
	gluPerspective(m_seeAngle,m_dblAspect,m_seeNearest,m_seeFarthest);
	//**End code for GL resize!

	wglMakeCurrent( NULL, NULL );
    ::ReleaseDC( this->m_hWnd, hDC );
	
}

void CMiner3D_viewerCtrl::OnPaint() 
{
	CPaintDC dc(this); // device context for painting
	
	// TODO: Add your message handler code here

	wglMakeCurrent(dc.m_hDC,hRC);
	
	//**Draw GL here!
	COLORREF color=TranslateColor(GetBackColor());
	
    if (m_fogDensity)
	{
		glEnable(GL_FOG);
		{
			GLfloat fogColor[4] = {
				((float)(m_fogColor&0xFF))/255,
				((float)((m_fogColor&0xFF00)>>8))/255,
				((float)((m_fogColor&0xFF0000)>>16))/255,
				1.0};
			glFogi (GL_FOG_MODE, GL_EXP);
			glFogfv (GL_FOG_COLOR, fogColor);
			glFogf (GL_FOG_DENSITY, m_fogDensity);
			glHint (GL_FOG_HINT, GL_DONT_CARE);
		}
	}
	glClearColor(
				((float)(color&0xFF))/255,
				((float)((color&0xFF00)>>8))/255,
				((float)((color&0xFF0000)>>16))/255,
				0.0);
	glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);

	glMatrixMode(GL_MODELVIEW);
	glLoadIdentity();
	gluLookAt(m_camPosX,m_camPosY,m_camPosZ,
			  m_camPosX+m_camDirX,m_camPosY+m_camDirY,m_camPosZ+m_camDirZ,
			  0.0,1.0,0.0);

	glEnable(GL_DEPTH_TEST);
	glEnable(GL_LIGHTING);	
	glEnable(GL_LIGHT0);
	
	if(m_light1)
	{
		GLfloat light1_diffuse[] = { 0.4f, 0.4f, 0.4f, 0.4f };
		GLfloat light1_position[] = { 0.0f, 1000.0f, 0.0f, 1.0f };
		glLightfv(GL_LIGHT1, GL_DIFFUSE, light1_diffuse);
		glLightfv(GL_LIGHT1, GL_POSITION, light1_position);
		glEnable(GL_LIGHT1);
	}
		
	m_tc.Draw(GL_RENDER);
	m_cc.Draw();
	m_pc.Draw();
	m_fc.Draw();
	if (m_wireVisible) m_wc.Draw();
	
	if(m_light1) glDisable(GL_LIGHT1);
	glDisable(GL_LIGHT0);
	glDisable(GL_LIGHTING);
	glDisable(GL_DEPTH_TEST);
    if (m_fogDensity) glDisable(GL_FOG);
	//**End code for draw GL!
	
	SwapBuffers(dc.m_hDC);
	wglMakeCurrent(NULL,NULL);
	
	//int cx=m_intWidth/2,cy=m_intHeight/2;
	//dc.Ellipse(CRect(cx-2,cy-2,cx+2,cy+2));
	
	//dc.SetBkMode(TRANSPARENT);
	//dc.SetTextColor(0x00ffffff);
	//dc.DrawText("",-1,CRect(0,0,m_intHeight,m_intWidth),DT_SINGLELINE);
	
	// Do not call COleControl::OnPaint() for painting messages
}

////////////////////////properties

void CMiner3D_viewerCtrl::OnIntervalChanged() 
{
	// TODO: Add notification handler code
	KillTimer(1000);
	if (m_interval)	SetTimer(1000,m_interval,NULL);

	SetModifiedFlag();
}

void CMiner3D_viewerCtrl::OnCharRotateDegreeChanged() 
{
	// TODO: Add notification handler code
	m_cc.rotate=m_charRotateDegree;

	SetModifiedFlag();
}

void CMiner3D_viewerCtrl::OnSeeAngleChanged() 
{
	// TODO: Add notification handler code
	RefreshSize();

	SetModifiedFlag();
}

void CMiner3D_viewerCtrl::OnSeeNearestChanged() 
{
	// TODO: Add notification handler code
	RefreshSize();

	SetModifiedFlag();
}

void CMiner3D_viewerCtrl::OnSeeFarthestChanged() 
{
	// TODO: Add notification handler code
	RefreshSize();

	SetModifiedFlag();
}

void CMiner3D_viewerCtrl::OnFogColorChanged() 
{
	// TODO: Add notification handler code

	SetModifiedFlag();
}

void CMiner3D_viewerCtrl::OnFogDensityChanged() 
{
	// TODO: Add notification handler code

	SetModifiedFlag();
}

void CMiner3D_viewerCtrl::OnPickLessExactChanged() 
{
	// TODO: Add notification handler code

	SetModifiedFlag();
}

void CMiner3D_viewerCtrl::OnCamPosXChanged() 
{
	// TODO: Add notification handler code

	SetModifiedFlag();
}

void CMiner3D_viewerCtrl::OnCamPosYChanged() 
{
	// TODO: Add notification handler code

	SetModifiedFlag();
}

void CMiner3D_viewerCtrl::OnCamPosZChanged() 
{
	// TODO: Add notification handler code

	SetModifiedFlag();
}

void CMiner3D_viewerCtrl::OnCamAxzChanged() 
{
	// TODO: Add notification handler code
	UpdateCamDir();

	SetModifiedFlag();
}

void CMiner3D_viewerCtrl::OnCamAzyChanged() 
{
	// TODO: Add notification handler code
	UpdateCamDir();

	SetModifiedFlag();
}

////////////////////////Method

void CMiner3D_viewerCtrl::ClearAll() 
{
	// TODO: Add your dispatch handler code here
	m_cc.RemoveAll();
	m_tc.RemoveAll();
	m_pc.RemoveAll();
	m_fc.RemoveAll();
	m_wc.RemoveAll();
}

BOOL CMiner3D_viewerCtrl::AddTile(long id, double x, double y, double z) 
{
	// TODO: Add your dispatch handler code here
	if (m_tc.Add(id,x,y,z)==NULL) return FALSE;

	return TRUE;
}

BOOL CMiner3D_viewerCtrl::AddChar(short c, double x, double y, double z) 
{
	// TODO: Add your dispatch handler code here
	if (m_cc.Add(c,x,y,z)==NULL) return FALSE;

	return TRUE;
}

void CMiner3D_viewerCtrl::Refresh() 
{
	// TODO: Add your dispatch handler code here
	RedrawWindow();

}

void CMiner3D_viewerCtrl::OpenTile(long id) 
{
	// TODO: Add your dispatch handler code here
	TileNode *p=m_tc.Get(id);
	if (p==NULL) return;
	p->opening=TRUE;
}

void CMiner3D_viewerCtrl::ChangeTileColor(long id, OLE_COLOR color) 
{
	// TODO: Add your dispatch handler code here
	TileNode *p=m_tc.Get(id);
	if (p==NULL) return;
	p->t.m_materialColor[0]=((float)(color&0xFF))/255;
	p->t.m_materialColor[1]=((float)((color&0xFF00)>>8))/255;
	p->t.m_materialColor[2]=((float)((color&0xFF0000)>>16))/255;

}

BOOL CMiner3D_viewerCtrl::AddColorTile(long id, double x, double y, double z, OLE_COLOR color) 
{
	// TODO: Add your dispatch handler code here
	TileNode *p=m_tc.Add(id,x,y,z);
	if (p==NULL) return FALSE;
	p->t.m_materialColor[0]=((float)(color&0xFF))/255;
	p->t.m_materialColor[1]=((float)((color&0xFF00)>>8))/255;
	p->t.m_materialColor[2]=((float)((color&0xFF0000)>>16))/255;

	return TRUE;
}

long CMiner3D_viewerCtrl::Pick(double x, double y, BOOL FAR* miss) 
{
	// TODO: Add your dispatch handler code here
    GLuint selectBuf[4096];
    GLint hits;
    GLint viewport[4];
	int n=0;
try
{
	GLdouble px=m_camPosX;
	GLdouble py=m_camPosY;
	GLdouble pz=m_camPosZ;

	HDC hDC = ::GetDC(this->m_hWnd);
	wglMakeCurrent(hDC,hRC);

    glGetIntegerv (GL_VIEWPORT, viewport);
    glSelectBuffer (4096, selectBuf);
	
	glRenderMode(GL_SELECT);				// Enter the SELECT render mode
    glInitNames();
    glPushName(-1);

    glMatrixMode (GL_PROJECTION);
    glPushMatrix ();
        glLoadIdentity ();
        gluPickMatrix((GLdouble)x, (GLdouble) (viewport[3] -y), m_pickLessExact, m_pickLessExact, viewport);
		gluPerspective(m_seeAngle,m_dblAspect,m_seeNearest,m_seeFarthest);
		glMatrixMode(GL_MODELVIEW);
		//m_cc.Draw(GL_SELECT);
		m_tc.Draw(GL_SELECT);
    glPopMatrix ();
    glFlush ();

    hits = glRenderMode (GL_RENDER);
	
	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glViewport(0,0,m_intWidth,m_intHeight);
	gluPerspective(m_seeAngle,m_dblAspect,m_seeNearest,m_seeFarthest);
    
	wglMakeCurrent( NULL, NULL );
    ::ReleaseDC( this->m_hWnd, hDC );
	
	if (hits)
	{
		TileNode *tp=m_tc.Get(selectBuf[3]);
		double d,minz=SqrDistance(tp->t.x,tp->t.y,tp->t.z,px,py,pz);
		//CString str;str.Format("%d %f %f",selectBuf[3+n*4],d,minz);AfxMessageBox(str);
		for(int i=1;i<hits;i++)
		{
			tp=m_tc.Get(selectBuf[3+i*4]);
			d=SqrDistance(tp->t.x,tp->t.y,tp->t.z,px,py,pz);
			if (d<minz) {n=i;minz=d;}
		}
		*miss=FALSE;
	}
	else
	{
		*miss=TRUE;
		return 0;
	}
	//CString str;str.Format("%d",selectBuf[3+n*4]);AfxMessageBox(str);
}
catch(...)
{
	AfxMessageBox("???");
}

	return selectBuf[3+n*4];
}

BOOL CMiner3D_viewerCtrl::OnProperties(LPMSG lpMsg, HWND hWndParent, LPCRECT lpRect) 
{
	// TODO: Add your specialized code here and/or call the base class
	
	return TRUE;//return COleControl::OnProperties(lpMsg, hWndParent, lpRect);
}

void CMiner3D_viewerCtrl::OnLButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if (point.x>=0 && point.x<=m_intWidth && point.y>=0 && point.y<=m_intHeight)
		FireLeftButtonDown(point.x,point.y,(nFlags&MK_CONTROL)?TRUE:FALSE,(nFlags&MK_SHIFT)?TRUE:FALSE);
	
	COleControl::OnLButtonDown(nFlags, point);
}

void CMiner3D_viewerCtrl::OnRButtonDown(UINT nFlags, CPoint point) 
{
	// TODO: Add your message handler code here and/or call default
	if (point.x>=0 && point.x<=m_intWidth && point.y>=0 && point.y<=m_intHeight)
		FireRightButtonDown(point.x,point.y,(nFlags&MK_CONTROL)?TRUE:FALSE,(nFlags&MK_SHIFT)?TRUE:FALSE);
	
	COleControl::OnRButtonDown(nFlags, point);
}

void CMiner3D_viewerCtrl::RefreshSize()
{
	HDC hDC = ::GetDC(this->m_hWnd);
	wglMakeCurrent(hDC,hRC);

	glMatrixMode(GL_PROJECTION);
	glLoadIdentity();
	glViewport(0,0,m_intWidth,m_intHeight);
	gluPerspective(m_seeAngle,m_dblAspect,m_seeNearest,m_seeFarthest);
	
	wglMakeCurrent( NULL, NULL );
    ::ReleaseDC( this->m_hWnd, hDC );
}

void CMiner3D_viewerCtrl::PlayMidiFile(LPCTSTR filename) 
{
	// TODO: Add your dispatch handler code here
	PlayMusic(m_hWnd,filename);

}

void CMiner3D_viewerCtrl::StopPlayMidi() 
{
	// TODO: Add your dispatch handler code here
	CloseMusic();

}

void CMiner3D_viewerCtrl::OnMciNotify(WPARAM w,LPARAM l)
{
	if (w == MCI_NOTIFY_SUCCESSFUL) FireEndPlayMidi();
}

BOOL CMiner3D_viewerCtrl::PreTranslateMessage(MSG* pMsg) 
{
	// TODO: Add your specialized code here and/or call the base class
	switch (pMsg->message)
	{
		case WM_KEYDOWN:
			if ((pMsg->lParam&0x40000000)==0)
				FireVcKeyDown(pMsg->wParam,0);
			break;
		case WM_KEYUP:
			FireVcKeyUp(pMsg->wParam,0);
			break;
	}
	
	return COleControl::PreTranslateMessage(pMsg);
}

void CMiner3D_viewerCtrl::UpdateCamDir()
{
	m_camDirX=cos(m_camAxz)*cos(m_camAzy);
	m_camDirY=sin(m_camAzy);
	m_camDirZ=sin(m_camAxz)*cos(m_camAzy);
}

double CMiner3D_viewerCtrl::GetCamDirX() 
{
	// TODO: Add your dispatch handler code here
	return m_camDirX;

}

double CMiner3D_viewerCtrl::GetCamDirY() 
{
	// TODO: Add your dispatch handler code here
	return m_camDirY;

	return 0.0;
}

double CMiner3D_viewerCtrl::GetCamDirZ() 
{
	// TODO: Add your dispatch handler code here
	return m_camDirZ;

	return 0.0;
}


BOOL CMiner3D_viewerCtrl::AddPoint(double x, double y, double z) 
{
	// TODO: Add your dispatch handler code here
	if (m_pc.Add(x,y,z)==NULL) return FALSE;

	return TRUE;
}

BOOL CMiner3D_viewerCtrl::AddFace(short way, double c, double cx, double cy, double large, OLE_COLOR color) 
{
	// TODO: Add your dispatch handler code here
	if (m_fc.Add(way,c,cx,cy,large,color)==NULL) return FALSE;

	return TRUE;
}

void CMiner3D_viewerCtrl::OnLight1Changed() 
{
	// TODO: Add notification handler code

	SetModifiedFlag();
}

double sqr(double d)
{
	return d*d;
}

GLdouble CMiner3D_viewerCtrl::SqrDistance(GLdouble x1, GLdouble y1, GLdouble z1,GLdouble x2, GLdouble y2, GLdouble z2)
{
	return(sqr(x1-x2)+sqr(y1-y2)+sqr(z1-z2));
}

BOOL CMiner3D_viewerCtrl::GetTilePos(short id, double FAR* x, double FAR* y, double FAR* z) 
{
	// TODO: Add your dispatch handler code here
	TileNode *p=m_tc.Get(id);
	if (p==NULL) return FALSE;

	*x=p->t.x;
	*y=p->t.y;
	*z=p->t.z;

	return TRUE;
}

BOOL CMiner3D_viewerCtrl::AddWireTile(double x, double y, double z) 
{
	// TODO: Add your dispatch handler code here
	if (m_wc.Add(x,y,z)==NULL) return FALSE;

	return TRUE;
}

BOOL CMiner3D_viewerCtrl::AddColorWireTile(double x, double y, double z, OLE_COLOR color) 
{
	// TODO: Add your dispatch handler code here
	WireTileNode *p=m_wc.Add(x,y,z);
	if (p==NULL) return FALSE;
	p->t.m_materialColor[0]=((float)(color&0xFF))/255;
	p->t.m_materialColor[1]=((float)((color&0xFF00)>>8))/255;
	p->t.m_materialColor[2]=((float)((color&0xFF0000)>>16))/255;

	return TRUE;
}

void CMiner3D_viewerCtrl::OnWireVisibleChanged() 
{
	// TODO: Add notification handler code

	SetModifiedFlag();
}


OLE_HANDLE CMiner3D_viewerCtrl::GetHandleActiveWindow() 
{
	// TODO: Add your dispatch handler code here
	CWnd *w=GetActiveWindow();
	if(w==NULL) return NULL;

	return (OLE_HANDLE)w->m_hWnd;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Junior)
Vietnam Vietnam
My subject is Information technology. I like programming and learn more about everything.

Comments and Discussions