00001 #if !defined(AFX_OPENGLWND_H__83310F64_5D53_44AE_9D08_E29D6A961D6F__INCLUDED_) 00002 #define AFX_OPENGLWND_H__83310F64_5D53_44AE_9D08_E29D6A961D6F__INCLUDED_ 00003 00004 #if _MSC_VER > 1000 00005 #pragma once 00006 #endif // _MSC_VER > 1000 00007 // OpenGLWnd.h : header file 00008 // 00009 00010 #include "BaseOGLVRMLModelRenderer.h" 00011 00012 // Intels jpg library 00013 #include "ijl/ijl.h" 00014 00015 00016 class CExample3Doc; 00017 00018 00019 00020 /** The OpenGL-enabled view with the rendering loop and basic interaction. 00021 * Handles all the basic OpenGL initializations and, through VRMLRenderer, provides 00022 * the rendering and basic mouse and keyboard interaction (camera control, rendering modes). 00023 * It can render one or more objects of type VRMLModel; these are typically the virtual character models, but 00024 * other objects can be loaded and rendered in the scene. 00025 * 00026 * Unless there are special needs other than regular real-time rendering 00027 * and interaction, it is recommended to simply reuse 00028 * this class as it is by copying the OpenGLWnd.cpp and OpenGLWnd.h files 00029 * into your new project, and use it in the same way as demonstrated 00030 * in the examples. If you are building a new application, the detailed step-by-step 00031 * procedure is given in the 00032 * <a href="../../../../doc/index.html#building">section on Building a new application from scratch on the visage|SDK main page</a>. 00033 * In this case, it should not be necessary to enter the 00034 * details of this class. 00035 * 00036 * The rendering loop is implemented by starting a timer (InitOpenGL() function does this), so that the OnTimer function is called every 00037 * mTIMER_RENDERING_INTERVAL milliseconds (default is 20 milliseconds). This function calls RenderToScreen() in order to draw the models. 00038 * The actual drawing is performed in the base class BaseOGLVRMLModelRenderer. COpenGLWnd provides the 00039 * hook to the MFC window. 00040 * 00041 * This class implements the following interactions that are available to the user: 00042 * - Right mouse button + move mouse rotates the model. 00043 * - Left mouse button + move mouse translates the model. 00044 * - Control + left mouse button + move mouse zooms image. 00045 * - F11 repositions model to center of window. 00046 * - F1 sets rendering mode to wireframe. 00047 * - F2 sets rendering mode to solid. 00048 * 00049 * If it is desired to bypass the interactive camera control, it is possible to control the camera using 00050 * the COpenGLWnd::SetModelViewMatrix() function. 00051 * 00052 * In this example it is also demonstrated how to add a background image to the application. This is done in the function 00053 * SetContext(), which is called in every frame before the rendering. This function is a good place to insert other effects as well. 00054 * 00055 * For the user interested to modify the rendering process or implement their own, here is how it works. First, the renderer is initialized 00056 * by calling COpenGLWnd::InitOpenGL() (this is done in COpenGLWnd::OnCreate() so the application developer does not need to do it). The COpenGLWnd::InitOpenGL() function initializes the rendering, and starts the rendering timer. The timer 00057 * calls the function COpenGLWnd::RenderToScreen() (through the function OnTimer()) every 20 milliseconds (mTIMER_RENDERING_INTERVAL). 00058 * The COpenGLWnd::RenderToScreen() renders all models that are attached to the renderer. The actual implementation of the rendering 00059 * is in the parent class, BaseOGLVRMLModelRenderer::RenderToScreen(). The models are attached to the renderer 00060 * using the COpenGLWnd::Init() function. In this example this is done in CExample1Doc::LoadVCModelFile(). Once the model is attached to 00061 * the renderer, the renderer will keep rendering it until it is removed. Note that the rendering loop (implemented by the 00062 * timer mechanism) and the animation loop(s) implemented by FAPlayer are running asynchronously in separate threads. The FAPlayer 00063 * updates the VRMLModel in its animation loop, and the renderer (COpenGLWnd) renders it in every rendering cycle. To avoid 00064 * rendering partially animated models, the flag VRMLModel::locked is used. This flag is set by both animation and rendering 00065 * loops during critical operation to make sure that the other loop waits until the operation is finished. In this way, multiple 00066 * virtual characters can be animated, each in its own FAPlayer running in a separate thread, and they are all rendered by 00067 * the renderer. 00068 */ 00069 class COpenGLWnd : public CView, public BaseOGLVRMLModelRenderer 00070 { 00071 public: 00072 00073 bool DrawBackgroundImage(); 00074 int COpenGLWnd::LoadTexture(char *fullPath); 00075 00076 protected: 00077 00078 // ID's to identify callbacks on timers. 00079 enum ID_TIMER_EVENTS { 00080 ID_ROTATE = 1, 00081 ID_RENDERING = 2 }; 00082 00083 static const int mTIMER_ROTATE_INTERVAL; 00084 static const int mTIMER_RENDERING_INTERVAL; 00085 00086 PIXELFORMATDESCRIPTOR pfdMain; 00087 00088 // We can recieve mouse move events even though left button has not been pressed. 00089 // This occurs for example when a dialogbox is opened upon the window. 00090 bool mLeftButtonDown; 00091 00092 bool mRightButtonDown; 00093 00094 bool rendererBusy; 00095 00096 // needed for background image drawing 00097 GLuint bgtexture[1]; 00098 00099 00100 // ------------------------------------------------- 00101 // VisualC++ added code below 00102 // ------------------------------------------------- 00103 00104 protected: 00105 COpenGLWnd(); // protected constructor used by dynamic creation 00106 DECLARE_DYNCREATE(COpenGLWnd) 00107 00108 // Attributes 00109 public: 00110 // void (*m_RenderScene) ( CViewerDoc* doc ); // void function pointer to the rendering 00111 // function. Used to change to easily 00112 // change what a viewport displays. 00113 protected: 00114 HGLRC m_hRC; //Rendering Context 00115 CDC* m_pDC; //Device Context 00116 00117 // HDC m_hDC; 00118 00119 // Operations 00120 public: 00121 BOOL InitOpenGL(); 00122 bool m_bSwap; 00123 // OpenGL init stuff 00124 BOOL SetupPixelFormat(); 00125 00126 // Each viewport uses its own context 00127 // so we need to make sure the correct 00128 // context is set whenever we make an 00129 // OpenGL command. Here we also clear the screen. 00130 void SetContext(); 00131 void SwapGLBuffers() { SwapBuffers(m_pDC->GetSafeHdc());wglMakeCurrent(NULL, NULL);}; 00132 void StartRenderingTimer(); 00133 00134 // Overrides 00135 // ClassWizard generated virtual function overrides 00136 //{{AFX_VIRTUAL(COpenGLWnd) 00137 public: 00138 protected: 00139 virtual void OnDraw(CDC* pDC); // overridden to draw this view 00140 virtual BOOL PreCreateWindow(CREATESTRUCT& cs); 00141 //}}AFX_VIRTUAL 00142 00143 // Implementation 00144 protected: 00145 virtual ~COpenGLWnd(); 00146 00147 #ifdef _DEBUG 00148 virtual void AssertValid() const; 00149 virtual void Dump(CDumpContext& dc) const; 00150 #endif 00151 00152 // Generated message map functions 00153 protected: 00154 //{{AFX_MSG(COpenGLWnd) 00155 afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); 00156 afx_msg BOOL OnEraseBkgnd(CDC* pDC); 00157 afx_msg void OnSize(UINT nType, int cx, int cy); 00158 afx_msg void OnLButtonDown(UINT nFlags, CPoint point); 00159 afx_msg void OnRButtonDown(UINT nFlags, CPoint point); 00160 afx_msg void OnMouseMove(UINT nFlags, CPoint point); 00161 afx_msg void OnRButtonUp(UINT nFlags, CPoint point); 00162 afx_msg void OnTimer(UINT nIDEvent); 00163 afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags); 00164 afx_msg void OnLButtonUp(UINT nFlags, CPoint point); 00165 //}}AFX_MSG 00166 DECLARE_MESSAGE_MAP() 00167 private: 00168 bool m_bShowPopup; 00169 bool m_bTimerSet; 00170 00171 00172 00173 00174 00175 00176 00177 00178 public: 00179 /** 00180 * Initialise the renderer with a VRMLModel to render. 00181 * Standard rendering mode is set. 00182 * The view is set such that the model is fully visible on screen. 00183 * 00184 * This function can be called several times with different 00185 * models in case more than one model is rendered. Up to 1000 models are supported. 00186 * 00187 * @param initModel the model to load in the renderer. 00188 */ 00189 void Init(VRMLModel *initModel); 00190 00191 /** 00192 * Render the model to screen. 00193 * Render the loaded model to screen. If no model is loaded, clears the screen. 00194 */ 00195 void RenderToScreen(); 00196 00197 /** 00198 * Set the model view matrix (for camera control). 00199 * 00200 * This can be used to control the camera view. This matrix will be loaded using glLoadMatrixf(). glMatrixMode is set to GL_MODELVIEW. 00201 * If m is 0, the default camera control mode is used. In the default mode, the renderer first sets the view 00202 * automatically based on the size of the model, and then the camera is controlled interactively by the user 00203 * using the mouse. 00204 * 00205 * @param m the modelview matrix to be loaded. 00206 */ 00207 void SetModelViewMatrix(GLfloat *m); 00208 00209 00210 /** 00211 * The rendering mode. 00212 * The rendering mode can be: 00213 * - VGLR_RENDERING_WIREFRAME for the wireframe mode 00214 * - VGLR_RENDERING_AS_IS for the "standard" lighted, smooth shaded mode 00215 */ 00216 enum VGLR_RENDERING_MODE { 00217 VGLR_RENDERING_WIREFRAME, 00218 VGLR_RENDERING_SOLID_NO_MATERIAL, 00219 VGLR_RENDERING_MATERIAL, 00220 VGLR_RENDERING_AS_IS }; 00221 00222 00223 00224 /** 00225 * Resize window. 00226 * Resize And Initialize The GL Window. 00227 * @param width the width of the window. 00228 * @param height the height of the window. 00229 */ 00230 void ReSizeGLScene(GLsizei width, GLsizei height); 00231 00232 00233 /** 00234 * Sets the renderingmode. 00235 * The rendering mode can be: 00236 * - VGLR_RENDERING_WIREFRAME for the wireframe mode 00237 * - VGLR_RENDERING_AS_IS for the "standard" lighted, smooth shaded mode 00238 */ 00239 void SetRenderingMode(VGLR_RENDERING_MODE newMode); 00240 00241 00242 /** 00243 * The interaction for pressing the left mouse button. 00244 * The left mouse button is used for moving the model horizontaly and verticaly. 00245 * @param x x position of the mouse. 00246 * @param y y position of the mouse. 00247 */ 00248 void LeftButtonDown(int x, int y); 00249 00250 /** 00251 * The interaction for pressing the right mouse button. 00252 * The right mouse button is used for rotating the model. 00253 * @param x x position of the mouse. 00254 * @param y y position of the mouse. 00255 */ 00256 void RightButtonDown(int x, int y); 00257 00258 /** 00259 * The interaction for pressing the left mouse button while CTRL is held. 00260 * CTRL + left mouse button is used for zooming. 00261 * @param x x position of the mouse. 00262 * @param y y position of the mouse. 00263 */ 00264 void LeftButtonControlDown(int x, int y); 00265 00266 /** 00267 * The interaction for dragging the left mouse button. 00268 * The left mouse button is used for moving the model horizontaly and verticaly. 00269 * @param x x position of the mouse. 00270 * @param y y position of the mouse. 00271 */ 00272 void LeftButtonDrag(int x, int y); 00273 00274 /** 00275 * The interaction for dragging the right mouse button. 00276 * The right mouse button is used for rotating the model. 00277 * @param x x position of the mouse. 00278 * @param y y position of the mouse. 00279 */ 00280 void RightButtonDrag(int x, int y); 00281 00282 /** 00283 * The interaction for dragging the left mouse button while CTRL is held. 00284 * CTRL + left mouse button is used for zooming. 00285 * @param x x position of the mouse. 00286 * @param y y position of the mouse. 00287 */ 00288 void LeftButtonControlDrag(int x, int y); 00289 00290 /** 00291 * The interaction for dragging the right mouse button. 00292 * The right mouse button is used for rotating the model. This function is called by a timer 00293 * in order to keep rotating the model when the user drags the mouse with the right button 00294 * down, then holds it in place while still keeping the button down. 00295 */ 00296 void RightButtonDownTimerFunc(); 00297 00298 00299 /** 00300 * Toggle backface culling. 00301 * Toggle the backface culling on or off. 00302 */ 00303 void ToggleBackfaceCull(); 00304 00305 /** 00306 * Re-positions model onscreen. 00307 * Re-positions model onscreen based on the previously obtained 00308 * measurements of the model. Basically, this resets the view. 00309 */ 00310 void FitToScreen(); 00311 00312 /** Fits the model to screen with a zoom factor. 00313 * The FitToScreen() function sometimes does not provide a satisfactory result. This function allows 00314 * to correct by zooming in or out with respect to the original result produced by FitToScreen(). 00315 * @param zoom The zoom factor. 1.0 is the regular fit. Bigger number zooms out (good for smaller windows). 00316 * 00317 */ 00318 void FitToScreen(float zoom); 00319 00320 /** 00321 * Closes down and resets renderer. 00322 */ 00323 void Close(); 00324 00325 /** 00326 * Frame rate. Calculated based on the last 50 rendered frames. 00327 */ 00328 float renderingFrameRate; 00329 00330 00331 private: 00332 // Current translationvalues. 00333 GLfloat mXTranslate, mYTranslate, mZTranslate; 00334 00335 // Original fittingvalues stored to use when user wants FitToScreen() 00336 GLfloat mXTranslateFit, mYTranslateFit, mZTranslateFit; 00337 00338 // modelViewMatrix set by the user, if any 00339 GLfloat *modelViewMatrix; 00340 00341 GLfloat mXAccel, mYAccel, mZAccel; 00342 00343 GLfloat mLeftButtonX; 00344 GLfloat mLeftButtonY; 00345 GLfloat mRightButtonX; 00346 GLfloat mRightButtonY; 00347 00348 GLfloat mRotateXAngleAdd; 00349 GLfloat mRotateYAngleAdd; 00350 00351 GLfloat mLeftButtonControlZ; 00352 00353 GLfloat mXRotAngle; 00354 GLfloat mYRotAngle; 00355 00356 GLfloat mMaxRadius; 00357 00358 double mVGLR_PERSPECT_FOVY; 00359 double mVGLR_PERSPECT_TAN_FOVY; 00360 double mVGLR_PERSPECT_NEAR_PLANE; 00361 00362 GLfloat mFarPlane; 00363 00364 GLsizei mWindowWidth, mWindowHeight; 00365 00366 // Converted to world space coordinates. 00367 vector<Point3d> mStoredVerts; 00368 00369 00370 // Which rendering-mode are we in? 00371 VGLR_RENDERING_MODE mRenderingMode; 00372 00373 // Backface culling. 00374 bool mBackfaceCull; 00375 }; 00376 00377 ///////////////////////////////////////////////////////////////////////////// 00378 00379 //{{AFX_INSERT_LOCATION}} 00380 // Microsoft Visual C++ will insert additional declarations immediately before the previous line. 00381 00382 #endif // !defined(AFX_OPENGLWND_H__83310F64_5D53_44AE_9D08_E29D6A961D6F__INCLUDED_)