/********************************************************************/
/* Copyright (c) 2019 System fugen G.K. and Yuzi Mizuno          */
/* All rights reserved.                                             */
/********************************************************************/
/**
 * @file fugenView.h
 * @brief クラス fugenView の宣言
 */
#if !defined(AFX_OPENGLWINDOW_H__FDFEE3CB_479A_496F_AA35_10A5F8D997D2__INCLUDED_)
#define AFX_OPENGLWINDOW_H__FDFEE3CB_479A_496F_AA35_10A5F8D997D2__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#include "mg/MGCL.h"
#include "mg/PickObjects.h"
#include "mgGL/sysGLList.h"
#include "mgGL/openglView.h"
#include "mgGL/ConstructionPlane.h"
#include "mgGL/VBOByScreen.h"

#include "GL/glew.h"
#include "Undo/IPlaneActionTarget.h"
#include "Undo/ICameraActionTarget.h"
#include "fugenDoc.h"
#include "CoordinateArrow.h"

#include "Misc/fugenPrinter.h"
#include "Misc/UserPreference.h"

struct IActionManager;
class CCameraAction;
class MGUnit_vector;
class MGPosition;
class MGStraight;
class MGCommandBase;
class MGContext;

// Standard OpenGL Init Stuff
bool SetupPixelFormat(HDC hdc, DWORD dwFlags);

// Default GLSLProgram Loading.
bool SetupGLSL(mgGLSLProgram* glslP);

/////////////////////////////////////////////////////////////////////////////
/// fugenView ビュー
class fugenView : public CView, public MGOpenGLView,
	public IPlaneActionTarget, public ICameraActionTarget
{
	DECLARE_DYNCREATE(fugenView)

public:
	///コンストラクタ
	fugenView(bool is_perspective=true);

	////////////// オペレーション ///////////////

	/// ピックイベント関連
	//@{
	/// （マウスによる）ピックを開始する。
	/// @param[in] point ピック開始時点でのマウスカーソルの位置。
	/// @throws no-throw
	/// @post m_is_LButton_down == true
	/// @post m_button_down_point == point
	/// @see EndPick, IsPicking
	void BeginPick(const CPoint& point);

	/// （マウスによる）ピックを終了する。
	/// @throws no-throw
	/// @post m_is_LButton_down == false
	/// @see BeginPick, IsPicking
	void EndPick();

	/// 現在（マウスによる）ピック中かをテストする。
	/// @throws no-throw
	/// @return ピック中ならば true を返す。
	/// @see BeginPick, EndPick
	bool IsPicking() const;
	//@}

	/// マウスムーヴ関連
	//@{
	void BeginTracking(UINT nFlags, const CPoint& point);
	void EndTracking();
	bool IsTracking() const;
	//@}

	/// IPlaneActionTarget
	//@{
	virtual IActionManager* GetActionManager();
	virtual const IActionManager* GetActionManager() const;
	virtual void SetActionManager(IActionManager* pMgr);

	virtual bool IsDirty() const{return false;};//To resolve IAction's IsDirty.
	virtual void SetDirtyFlag(bool bDirty = true){;};//To resolve IAction's.

	virtual MGConstructionPlane& GetCPlane();
	virtual void Refresh();
	//@}

	/// ICameraActionTarget
	//@{
	virtual IActionManager* GetCameraActionManager();
	virtual MGOpenGLView& GetCamera();
	//@}

	///Change Window's point coordinates to OpenGL's screen coordinate.
	void change_sc(
		const CPoint& point,	//Window's point coordinates.
		int& sx,int& sy//OpenGL's screen coordinates, whose origin is (left, bottom).
	)const;

	///Change Window's point coordinates to OpenGL's screen coordinate.
	void change_sc(
		int cx, int cy,	//Window's point coordinates.
		int& sx,int& sy//OpenGL's screen coordinates, whose origin is (left, bottom).
	)const;

	///Clear current objects(clear currents of doc and erase the display lists).
	void clearCurrentObjects();

	///Clear all windows' LButton down status under the document().
	void clearAllLButtonDownStatus();

	///Convert the world coordinates to the screen coordinates of the MFC.
	///1. One point version.
	void convert_to_screen(
		const MGPosition& wc,	//world coordinate.
		CPoint& sc				//screen coordinate
	);
	///2. Two point version.
	void convert_to_screen(
		const MGPosition& wc1,
		const MGPosition& wc2,
		CPoint& sc1,
		CPoint& sc2
	);
	///2. n point version.
	void convert_to_screen(
		const std::vector<MGPosition>& wc,
		std::vector<CPoint>& sc
	);

	///Get current objects reference.
	const MGPickObjects& current_objects()const{
		return document().current_objects();
	};

	void getModelViewProjectionMatrices(
		glm::mat4& modelM,//double modelM[16],
		glm::mat4& projM,//double projM[16],
		int vp[4]
	);

	virtual void copy_view_env(const fugenView& other);

	///Return the current command tool.
	MGCommandBase* current_command_tool();

	///display the (x,y,z) position in status bar.
	virtual void display_position_in_status_bar(const MGPosition& point) const;

	///display pos data in statue bar and set the data in doc.cursor().
	void displaySet_position(const MGPosition& pos);

	///display pos data in statue bar and set the data in doc.cursor().
	///Transfer the point to world coordinates, then display in the status bar.
	void displaySet_position(const CPoint& point);

	///Get the document of this view.
	fugenDoc& document(){return *(GetDocument());};

	///Get the document of this view.
	const fugenDoc& document()const{return *(GetDocument());};

	///Get the document of this view.
	fugenDoc* GetDocument(){ return (fugenDoc*)m_pDocument;};

	///Get the document of this view.
	const fugenDoc* GetDocument()const{ return (fugenDoc*)m_pDocument;};

	fugenView* get_main_view(){return document().get_main_view();};

	///Draw the coordinate system of the currently drawn view.
	virtual void updateAxisPictures(float scale=1.f);

	///Get the surface parameter value uv(u,v) where screen coordinate (sx,sy) is prjected on.
	///If no projection points are found, the nearest point to a perimeter of surf will
	///be returned.
	bool get_surface_parameter(
		const MGFSurface& surf,
		const CPoint& point,	//client area coordinates. (left, top) is (0,0).
		MGPosition& uv	//surface parameter (u,v) where (sx,sy) is projected on will be returned.
	)const;

	///hide the input gels.
	void hide_gels(const std::vector<const MGGel*>& gels_to_hide);
	void hide_gels(const MGPickObjects& gels_to_hide);

	///Transform to the home position.
	virtual void home();

	///Transform to the view whose origin is cplane's origin and
	//whose eys is on the normal of the cplane.
	virtual void cplaneHome();

	///Return if this is a 2D view or not.
	virtual bool is_2D() const{return false;};

	///標準ビューポートメンバーのひとつでメンバーの表示変更の反映を
	///受け付けるかどうか. TRUEのもののいずれかひとつでされた表示への
	///変更がfugenDocのデータを通してTRUEのすべてのビューに反映される。
	///Function's return value is:0(false) if not standard view.
	///1: 3D perspective view, 2:(x,y) 2D view, 3:(y,z) 2D view, 4:(z,x) 2D view
	virtual int is_standard_view() const{return 1;}

	///Test if this is the main view of the doc.
	bool is_mainView()const;

	///locate the window's screen coordinate to the 3D world coordinate.
	///In uv, the construction plane's parameter(u,v) coordinate will be returned.
	virtual MGPosition locate(const CPoint& point, MGPosition* uv=0)const;

	///Lock or unlock the window update.
	void lockWindowUpdate();
	void unlockWindowUpdate();

	///Make openGL display list in the input glview.
	virtual void makeDisplayList();

	/// Each viewport uses its own context, so we need to make sure the correct
	/// context is set whenever we make an OpenGL command.
	void make_RC_current(CDC* pDC=0);

	///Return the point when a mouse button was down.
	const CPoint& button_down_point()const{return m_button_down_point;};

	///returns the mouse move new point.
	const CPoint& mousemove_new_point()const{return m_mousemove_new_point;};

	///returns the mouse move old point.
	const CPoint& mousemove_old_point()const{return m_mousemove_old_point;};

	///Perform the panning view transformation from the
	///Windows point0 to point1.
	void pan(
		const CPoint& point0,
		const CPoint& point1
	);

	/// Returns all of objects that were inside the pick aperture.
	///pick will invoke make_RC_current();
	///Function's return value is the picked objects,
	///and the number of the picked objects is at most one.
	MGPickObjects pick(
		const CPoint& point, // client area position. (left, top) is (0, 0).
		const MGAbstractGels& objtypes = mgAll_Object, //Target pick object kind.
		//Target pick object kind. See MGGEL_KIND in "mg/types.h" or "mg/default.h"
		bool boundary=false,//true if the boundary of the gell is to select.
		double apx=-1.,//specifies pick aperture of x and y.
		double apy=-1.//When <=0. value is specified, default value(the value
		//obtained by pick_aperture() will be used.
	);

	///Determine if point is closer to the start point or to the end
	///of the curve curve.
	///Functin's return value is 0: if start point, 1: if end point.
	int pick_start_end(
		const MGCurve& curve,
		const CPoint& point	// client area coordinates. (left, top) is (0,0).
	);

	///Returns all of objects that were inside rectangle [pt1, pt2] into pobj.
	///pick will invoke make_RC_current();
	///function's return value is true: if pick_rect() was valid since pt1 and pt2 were different.
	///false: if pick_reck() was invalid since pt1 and pt2 were the same.
	///When false was returned, pobj will be unchanged
	bool pick_rect(
		const CPoint& pt1, // client area position. (left, top) is (0, 0).
		const CPoint& pt2, // the same as above
		MGPickObjects& pobj,
		const MGAbstractGels& objtypes = mgAll_Object //Target pick object kind.
		//Target pick object kind. See MGGEL_KIND in "mg/types.h" or "mg/default.h"
	);

	///Returns all of objects that were inside rectangle [pt1, pt2] into pobj.
	///pick will invoke make_RC_current();
	///function's return value is true: if pick_rect() was valid since pt1 and pt2 were different.
	///false: if pick_reck() was invalid since pt1 and pt2 were the same.
	///When false was returned, pobj will be unchanged
	bool pick_rect2(
		UINT nFlags,
		const CPoint& old_point,
		const CPoint& new_point,
		//Above parameters are of CWnd::OnLButtonDown. See the document.
		MGPickObjects& pobjs,//input(objects so far) and output(updated pobjs).
		const MGAbstractGels& types,//gell type to pick.
		bool multi_selection,	//true if multi gells can be selected.
		//false if only one is allowed to select.
		bool boundary=false//true if the boundary of the gell is to select.
	);

	///Pick an edge of the face f. That is, obtain the edge number
	///that passes input (sx,sy) when drawn in the current view matrix.
	///Function's return value is the edge pointer picked.
	///When no edges are picked, null will be returned.
	const MGEdge* pick_edge(
		const MGFace& f,
		const CPoint& point,	// client area coordinates. (left, top) is (0,0).
		float apx=-1.,//specifies pick aperture of x and y.
		float apy=-1.,//When <=0. value is specified, default value(the value
		//obtained by pick_aperture() will be used.
		MGPosition* uv=0	//surface parameter (u,v) nearest to (sx,sy) will be returned.
	);

	///Pick a perimeter of the surface surf. That is, obtain the perimeter number
	///that passes input (sx,sy) when drawn in the current view matrix.
	///Function's return value is perimeter number picked.
	///When no perimeters are picked, -1 will be returned.
	int pick_perimeter(
		const MGSurface& surf,
		const CPoint& point,	// client area coordinates. (left, top) is (0,0).
		double apx=-1.,//specifies pick aperture of x and y.
		double apy=-1.,//When <=0. value is specified, default value(the value
		//obtained by pick_aperture() will be used.
		MGPosition* uv=0//surface parameter (u,v) nearest to (sx,sy) will be returned.
	);

	///Test if right button is currently down.
	bool RButton_down()const{return m_is_RButton_down;};

	///Redraw the view. If this is a standarad view all of the 4 views will be drawn.
	///redraw will invoke make_RC_current();
	void redraw();

	///Redraw only this view. Even if this is a standard view, only this is redrawn.
	///redraw will invoke make_RC_current();
	virtual void redrawOnlythis(CDC* pDC=0);

	///Save the viewing context to the document.
	void save_view_context(MGContext& cxt);
	
	///Apply drawing attributes and colors of ctx to this.
	void apply_view_context_colors(MGContext& cxt);

	/// Apply construction plane's colors.
	/// Must be override View2D etc.
	virtual void apply_grid_colors(MGContext& cxt);

	///Show all objects
	void show_all_objects();

	///Transform the current view according to the mouse movement.
	virtual void mouse_move_transform(
		const CPoint& point	///<the new mouse location data after mouse movement.
	);

	/// Transform the world coordinates to the construction plane coordinates.
	void transform_cplane_coord(MGPosition& posWorld) const;

	///Convert the windows screen coordinate point to MGCL's straight line.
	void unproject_to_sl(const CPoint& point, MGStraight& sl) const;

	///Convert the windows world coordinate point to MGCL's straight line.
	void unproject_to_sl(const MGPosition& point, MGStraight& sl) const;

	///Get the original view direction vector.
	MGUnit_vector view_direction_original()const;

	///Initialize model.
	virtual void initializeModel();

	/// デフォルトのボックス枠を返す
	virtual const MGBox& defaultBoxModel()const; 

	///Terminate the doc's current command tool.
	void terminate_current_command_tool();

	/// シーン内に存在するすべてのモデルがビューにフィットするようにズーム
	void ZoomToAllExtents();
	/// 選択モデルがビューにフィットするようにズーム
	void ZoomToAllSelections();

	CDC* get_dc();
	void release_dc();
	
	virtual int getViewId() const { return (m_idView == -1)?is_standard_view():m_idView; };
	virtual void setViewId(int newId) {m_idView = newId;};
	
/// 操作履歴がつくカメラ位置移動処理
void ExecChangeCameraSetting(
	const MGVector& axisx,///< 作図平面の X 軸方向のワールド座標系表現。
	const MGVector& axisy ///< 作図平面の Y 軸方向のワールド座標系表現。
);

/// 操作履歴がつくカメラ位置移動処理
void ExecChangeViewport(
	const MGVector& eyeP,///The camera(eye) position vector that looks at the origin.
		///Only the direction is used.
		///The actual position is obtained by initializeViewingEnvironmentByBox().
	const MGVector& viewUpVector///view up vector.
);

/// 操作履歴がつくカメラのホームポジション戻し処理 (fugenView::initializeModel)
void ExecInitModel(
	const MGBox& box///<ズームする空間
);

/// 操作履歴がつくパン処理 (MGOpenGLView::translate)
void ExecPan(
	double dHorz,///<水平方向移動量
	double dVert///<垂直方向移動量
);

/// 操作履歴がつくズーム処理 (MGOpenGLView::pan_zoom)
/// @param[in] box ズームする空間
void ExecPanZoom(const MGBox& box);

/// 操作履歴がつくズーム処理 (MGOpenGLView::pan_zoom)
/// @param[in] x0 ズームするビュー領域のスクリーン座標左下 x 成分
/// @param[in] y0 ズームするビュー領域のスクリーン座標左下 y 成分
/// @param[in] x1 ズームするビュー領域のスクリーン座標右上 x 成分
/// @param[in] y1 ズームするビュー領域のスクリーン座標右上 y 成分
void ExecPanZoom(int x0, int y0, int x1, int y1);

/// 操作履歴がつく軸中心回転処理 (MGOpenGLView::rotate)
/// @param[in] dAngle 回転角（度で指定）
/// @param[in] dX 回転軸の方向ベクトル x 成分
/// @param[in] dY 回転軸の方向ベクトル y 成分
/// @param[in] dZ 回転軸の方向ベクトル z 成分
void ExecRotate(
	float dAngle,///The unit is degree.
	float dX,
	float dY,
	float dZ
);

/// 操作履歴がつくズーム処理 (MGOpenGLView::scale)
/// @param[in] dFactor 現在の MGOpenGLView::scale に乗じる係数
void ExecZoom(double dFactor, const CPoint* cpoint=nullptr);

//Get the view title of this view;
virtual CString viewTitle()const;

protected:
	/// OpenGL init stuff
	/// The processes are:
	/// (1) Set up OpenGL Rendering context(HGLRC) and GLSL program.
	/// (2) make MGOpenGLView for this window.
	/// (3) Import context from the document.
	///Function's return value is:
	///=True : successfulley initialized.
	///=False : Error detected.
	bool InitOpenGL();

	static HGLRC* getRenderingContext();
	static mgGLSLProgram* getDefaultGLSLProgram();

protected:

// オーバーライド
	// ClassWizard は仮想関数のオーバーライドを生成します。
	//{{AFX_VIRTUAL(fugenView)
	virtual void OnInitialUpdate();
	virtual void OnPrepareDC(CDC* pDC, CPrintInfo* pInfo = NULL);
	virtual void OnDraw(CDC* pDC);
	virtual void OnActivateView(BOOL bActivate, CView* pActivateView, CView* pDeactiveView);
	virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
	virtual void OnPrint(CDC* pDC, CPrintInfo* pInfo);
	virtual void OnUpdate(CView* pSender, LPARAM lHint, CObject* pHint);
	virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
	virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
	virtual void OnEndPrintPreview(CDC* pDC, CPrintInfo* pInfo, POINT point, CPreviewView* pView);
	//}}AFX_VIRTUAL

// インプリメンテーション
protected:
	virtual ~fugenView();
#ifdef _DEBUG
	virtual void AssertValid() const;
	virtual void Dump(CDumpContext& dc) const;
#endif

	// 生成されたメッセージ マップ関数
protected:

	//{{AFX_MSG(fugenView)
	afx_msg void OnContextMenu(CWnd* pWnd, CPoint point);
	afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
	afx_msg void OnDestroy();
	afx_msg BOOL OnEraseBkgnd(CDC* pDC);
	afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
	afx_msg void OnKeyUp(UINT nChar, UINT nRepCnt, UINT nFlags);
	afx_msg void OnLButtonDblClk(UINT nFlags, CPoint point);
	afx_msg void OnLButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnMButtonDblClk(UINT nFlags, CPoint point);
	afx_msg void OnMButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnMButtonUp(UINT nFlags, CPoint point);
	afx_msg void OnMouseMove(UINT nFlags, CPoint point);
	afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint point);
	afx_msg void OnRButtonDblClk(UINT nFlags, CPoint point);
	afx_msg void OnRButtonDown(UINT nFlags, CPoint point);
	afx_msg void OnRButtonUp(UINT nFlags, CPoint point);
	afx_msg BOOL OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message);
	afx_msg void OnSize(UINT nType, int cx, int cy);
	afx_msg void OnTimer(UINT_PTR  nIDEvent);

	afx_msg void OnCPlaneSwitch();
	afx_msg void OnCPlaneSwitchUpdateUI(CCmdUI*);

	afx_msg void OnDisplayHide();
	afx_msg void OnViewZoomExtentsAll();
	afx_msg void OnUpdateViewZoomExtentsAll(CCmdUI* pCmdUI);
	afx_msg void OnViewZoomSelectedAll();
	afx_msg void OnUpdateViewZoomSelectedAll(CCmdUI* pCmdUI);
	afx_msg void OnSelectInvert();
	afx_msg void OnUpdateCPlaneGrid(CCmdUI* pCmdUI);

	afx_msg void OnCPlaneUndo();
	afx_msg void OnUpdateCPlaneUndoUI(CCmdUI* pCmdUI);
	afx_msg void OnCPlaneRedo();
	afx_msg void OnUpdateCPlaneRedoUI(CCmdUI* pCmdUI);

	afx_msg void OnViewUndo();
	afx_msg void OnUpdateViewUndoUI(CCmdUI* pCmdUI);
	afx_msg void OnViewRedo();
	afx_msg void OnUpdateViewRedoUI(CCmdUI* pCmdUI);


	afx_msg void OnViewVolumePlan();
	afx_msg void OnViewVolumePerspective();
	afx_msg void OnUpdateViewVolumePlan(CCmdUI* pCmdUI);
	afx_msg void OnUpdateViewVolumePerspective(CCmdUI* pCmdUI);
	afx_msg void OnViewVolumeTop();
	afx_msg void OnViewVolumeBottom();
	afx_msg void OnViewVolumeLeft();
	afx_msg void OnViewVolumeRight();
	afx_msg void OnViewVolumeBack();
	afx_msg void OnViewVolumeFront();
	afx_msg void OnUpdateViewVolumeFront(CCmdUI* pCmdUI);
	afx_msg void OnUpdateViewVolumeBack(CCmdUI* pCmdUI);
	afx_msg void OnUpdateViewVolumeBottom(CCmdUI* pCmdUI);
	afx_msg void OnUpdateViewVolumeLeft(CCmdUI* pCmdUI);
	afx_msg void OnUpdateViewVolumeRight(CCmdUI* pCmdUI);
	afx_msg void OnUpdateViewVolumeTop(CCmdUI* pCmdUI);
	afx_msg void OnViewCameraCPlaneTop();
	afx_msg void OnUpdateViewCameraCPlaneTop(CCmdUI* pCmdUI);
	afx_msg void OnViewCameraCPlaneBottom();
	afx_msg void OnUpdateViewCameraCPlaneBottom(CCmdUI* pCmdUI);
	afx_msg void OnViewCameraCPlaneLeft();
	afx_msg void OnUpdateViewCameraCPlaneLeft(CCmdUI* pCmdUI);
	afx_msg void OnViewCameraCPlaneRight();
	afx_msg void OnUpdateViewCameraCPlaneRight(CCmdUI* pCmdUI);
	afx_msg void OnViewCameraCPlaneFront();
	afx_msg void OnUpdateViewCameraCPlaneFront(CCmdUI* pCmdUI);
	afx_msg void OnViewCameraCPlaneBack();
	afx_msg void OnUpdateViewCameraCPlaneBack(CCmdUI* pCmdUI);
	afx_msg void OnViewCameraTarget();
	afx_msg void OnUpdateViewCameraTarget(CCmdUI* pCmdUI);
	afx_msg void OnViewCameraCameraAndTarget();
	afx_msg void OnUpdateViewCameraCameraAndTarget(CCmdUI* pCmdUI);


	//}}AFX_MSG

	DECLARE_MESSAGE_MAP()

protected:

//Copy the enability of the parent's cplane.
void copyCplaneEnability(fugenView* pParent);

CoordinateArrow m_coordinateDrawer;///<VBO to draw coordinate on the left bottom.

private:
	CDC* m_pDC;//CDC pointer of this client DC.

	int m_locked;	//True(>0) if the update is inhibitted.
	CPoint m_button_down_point;//RButton_down or LButton_down's old point.
			//The point when the bottun was down, and not updated while the button is down.

	CPoint m_mousemove_new_point;//When mouse move event is detected(OnMouseMove), the address
			//is updated at the top of the event to track the mouse move.
	CPoint m_mousemove_old_point;//When mouse move event is detected(OnMouseMove), the address
			//is updated at the end of the process to track the mouse move.
	fugenPrinter m_printer;

	bool m_is_LButton_down;//true while LButton is down.
	bool m_is_RButton_down;//true while RButton is down.

	enum ViewOp{
		ViewOpRotation, ///< ビュー回転
		ViewOpPan, ///< パン
		ViewOpZoom, ///< ズーム
	};
	ViewOp m_viewop; ///< マウス移動時のビュー変換モード

	std::unique_ptr<IActionManager> m_spPlaneActionMgr; ///< 作業平面編集履歴
	std::unique_ptr<IActionManager> m_spCamActionMgr; ///< カメラ編集履歴
	std::unique_ptr<CCameraAction> m_spCamWork; ///< 作業用カメラ編集履歴

	//convert this pick objects to the pick objects that include boundary information.
	//function's return value is true if any was converted.
	bool convert_pick_object_to_boundary(
		const CPoint& point,	//screen position.
		MGPickObjects& pobjs//input and output.
		);

	//Redraw all the standard views.
	//redraw will invoke make_RC_current();
	void redrawAllStdViews();

	// View Id追加
	int m_idView;

};

///constant for updateAxisPictures.
#define DIST_FROM_CORNER 25
#define COORD_LENGTH 30
#define COORD_LENGTH2 COORD_LENGTH*2

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ は前行の直前に追加の宣言を挿入します。

#endif // !defined(AFX_OPENGLWINDOW_H__FDFEE3CB_479A_496F_AA35_10A5F8D997D2__INCLUDED_)
