00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #include <wx/dcclient.h>
00013 #include "glwindow.h"
00014 #include "rendermanager.h"
00015 #include "glgetproc.h"
00016 #include "camera.h"
00017
00018 using namespace VRUT;
00019
00020
00021
00022
00023 GLWindow::GLWindow()
00024 : wxGLCanvas((wxWindow *)NULL, wxID_ANY, (int *)NULL)
00025 {
00026 module = (RenderModule *)NULL;
00027 renderManager = (RenderManager *)NULL;
00028 glContext = (wxGLContext *)NULL;
00029 fsWindow = (wxWindow *)NULL;
00030 nbPageIndex = wxNOT_FOUND;
00031 beingReparented = 0;
00032 }
00033
00034
00035 GLWindow::GLWindow(wxWindow * parent,
00036 RenderModule * _module,
00037 RENDER_WINDOW_ID winID,
00038 wxPoint position,
00039 wxSize size,
00040 int * attribList,
00041 wxString title)
00042 : wxGLCanvas(parent, wxID_ANY, attribList, position, size, 0, title)
00043 {
00044 windowID = winID;
00045 module = _module;
00046 renderManager = (RenderManager *)NULL;
00047 glContext = (wxGLContext *)NULL;
00048 fsWindow = (wxWindow *)NULL;
00049 nbPageIndex = wxNOT_FOUND;
00050 beingReparented = 0;
00051
00052 KERNEL->GetMessageSink()->RegisterListener(this, Event::EVT_RENDER_FULLSCREEN_TOGGLE);
00053 KERNEL->GetMessageSink()->RegisterListener(this, Event::EVT_RENDER_FULLSCREEN_SET);
00054 Connect(wxID_ANY, Event::EVT_RENDER_FULLSCREEN_TOGGLE, wxCommandEventHandler(GLWindow::onCommandEvent), (wxObject *)NULL, this);
00055 Connect(wxID_ANY, Event::EVT_RENDER_FULLSCREEN_SET, wxCommandEventHandler(GLWindow::onCommandEvent), (wxObject *)NULL, this);
00056
00057 Connect(wxID_ANY, wxEVT_PAINT, wxPaintEventHandler(GLWindow::onPaint), (wxObject *)NULL, this);
00058 Connect(wxID_ANY, wxEVT_SIZE, wxSizeEventHandler(GLWindow::onResize), (wxObject *)NULL, this);
00059 Connect(wxID_ANY, wxEVT_KEY_DOWN, wxKeyEventHandler(GLWindow::onKeyEvent), (wxObject *)NULL, this);
00060 Connect(wxID_ANY, wxEVT_KEY_UP, wxKeyEventHandler(GLWindow::onKeyEvent), (wxObject *)NULL, this);
00061
00062 Connect(wxID_ANY, wxEVT_ENTER_WINDOW, wxMouseEventHandler(GLWindow::onMouseEvent), (wxObject *)NULL, this);
00063 Connect(wxID_ANY, wxEVT_LEAVE_WINDOW, wxMouseEventHandler(GLWindow::onMouseEvent), (wxObject *)NULL, this);
00064 Connect(wxID_ANY, wxEVT_LEFT_DOWN, wxMouseEventHandler(GLWindow::onMouseEvent), (wxObject *)NULL, this);
00065 Connect(wxID_ANY, wxEVT_LEFT_UP, wxMouseEventHandler(GLWindow::onMouseEvent), (wxObject *)NULL, this);
00066 Connect(wxID_ANY, wxEVT_LEFT_DCLICK, wxMouseEventHandler(GLWindow::onMouseEvent), (wxObject *)NULL, this);
00067 Connect(wxID_ANY, wxEVT_RIGHT_DOWN, wxMouseEventHandler(GLWindow::onMouseEvent), (wxObject *)NULL, this);
00068 Connect(wxID_ANY, wxEVT_RIGHT_UP, wxMouseEventHandler(GLWindow::onMouseEvent), (wxObject *)NULL, this);
00069 Connect(wxID_ANY, wxEVT_RIGHT_DCLICK, wxMouseEventHandler(GLWindow::onMouseEvent), (wxObject *)NULL, this);
00070 Connect(wxID_ANY, wxEVT_MIDDLE_DOWN, wxMouseEventHandler(GLWindow::onMouseEvent), (wxObject *)NULL, this);
00071 Connect(wxID_ANY, wxEVT_MIDDLE_UP, wxMouseEventHandler(GLWindow::onMouseEvent), (wxObject *)NULL, this);
00072 Connect(wxID_ANY, wxEVT_MIDDLE_DCLICK, wxMouseEventHandler(GLWindow::onMouseEvent), (wxObject *)NULL, this);
00073 Connect(wxID_ANY, wxEVT_MOTION, wxMouseEventHandler(GLWindow::onMouseEvent), (wxObject *)NULL, this);
00074 Connect(wxID_ANY, wxEVT_MOUSEWHEEL, wxMouseEventHandler(GLWindow::onMouseEvent), (wxObject *)NULL, this);
00075 }
00076
00077
00078 GLWindow::~GLWindow()
00079 {
00080 if (KERNEL && !KERNEL->IsExiting())
00081 KERNEL->GetMessageSink()->UnregisterListener(this);
00083 if (renderManager)
00084 renderManager->DestroyGLWindow(this);
00085 SAFE_DELETE(glContext);
00086 }
00087
00088
00089 void GLWindow::draw()
00090 {
00091 if (!IsShownOnScreen() || !module || !glContext || !KERNEL || KERNEL->IsExiting())
00092 return;
00093
00096 if (beingReparented)
00097 {
00098 wxCommandEvent rndEvt = Event::GET_EVT_RENDER_UPDATE(module->GetSceneID());
00099 KERNEL->GetMessageSink()->PostEvent(rndEvt);
00100 --beingReparented;
00101 return;
00102 }
00103
00104 Scene * scene = KERNEL->sceneManager->GetScene(module->GetSceneID());
00105 if (scene)
00106 {
00109 scene->UpdateBVH();
00111 int w = 0, h = 0;
00112 GetClientSize(&w, &h);
00113 scene->SetProjectionParams(module->GetCameraID(), w, h);
00114 }
00115
00116 SetCurrent(*glContext);
00117
00118 module->Draw();
00119 SwapBuffers();
00120 GLCHECKERROR;
00121
00123 frameRate.IncFrame();
00124 wxCommandEvent evt = Event::GET_EVT_RENDER_FRAMERATE(windowID, int(frameRate.GetFPS() * 1000));
00125 KERNEL->GetMessageSink()->PostEvent(evt);
00126 }
00127
00128
00129 void GLWindow::toggleFullscreen()
00130 {
00131 setFullscreen(!fsWindow);
00132 }
00133
00134
00135 void GLWindow::setFullscreen(bool fullscreen)
00136 {
00137 if (((fsWindow == (wxWindow *)NULL) == !fullscreen) ||
00138 beingReparented ||
00139 !IsShownOnScreen())
00140 return;
00141
00142 wxAuiNotebook * renderNotebook = KERNEL->GetMainWindow()->GetRenderNotebook();
00143 if (fsWindow)
00144 {
00145 wxWindow * fsParent = GetParent();
00146 Reparent(fsWindow);
00147 renderNotebook->InsertPage(nbPageIndex, this, GetName(), true);
00148 SetFocus();
00149 fsParent->Destroy();
00150 fsWindow = (wxWindow *)NULL;
00151 }
00152 else
00153 {
00154 fsWindow = GetParent();
00155 nbPageIndex = renderNotebook->GetPageIndex(this);
00156 wxASSERT_MSG(nbPageIndex != wxNOT_FOUND, wxT("<GLWindow>Render window not found in notebook pages"));
00157 renderNotebook->RemovePage(nbPageIndex);
00158
00159 wxFrame * frame = new wxFrame(GetParent(), wxID_ANY, GetName());
00160 frame->Connect(wxID_ANY, wxEVT_SIZE, wxSizeEventHandler(GLWindow::onResize), (wxObject *)NULL, this);
00161 Reparent(frame);
00162 frame->ShowFullScreen(true);
00163 SetFocus();
00164 }
00165 beingReparented = 10;
00166 KERNEL->GetMainWindow()->GetAUIManager()->Update();
00167 }
00168
00169
00170 void GLWindow::onPaint(wxPaintEvent & WXUNUSED(evt))
00171 {
00172 wxPaintDC(this);
00173 draw();
00174 }
00175
00176
00177 void GLWindow::onResize(wxSizeEvent & evt)
00178 {
00179 int w = 0, h = 0;
00180 GetClientSize(&w, &h);
00181 if (module && module->GetCameraID() != NODE_ID_NONE)
00182 {
00183 Scene * scene = KERNEL->sceneManager->GetScene(module->GetSceneID());
00184 if (scene)
00185 {
00186 NODE_ID camID = module->GetCameraID();
00187 scene->WriteLock(camID);
00188 scene->SetProjectionParams(camID, w, h);
00189 scene->WriteUnlock(camID);
00190 }
00191 }
00193 evt.m_size = GetClientSize();
00194 evt.Skip();
00195 }
00196
00197
00198 void GLWindow::onKeyEvent(wxKeyEvent & evt)
00199 {
00200 if (!module || !KERNEL || KERNEL->IsExiting())
00201 return;
00202
00203 evt.SetId(int(windowID));
00204 KERNEL->GetMessageSink()->ProcessEvent(evt);
00205 evt.Skip();
00206
00207 #ifdef EVENT_DEBUG
00208 LOG(wxT("<GLWindow>key event"));
00209 #endif
00210 }
00211
00212
00213 void GLWindow::onMouseEvent(wxMouseEvent & evt)
00214 {
00215 if (module && KERNEL && !KERNEL->IsExiting())
00216 {
00217 evt.SetId(int(windowID));
00218 KERNEL->GetMessageSink()->ProcessEvent(evt);
00219 }
00220 evt.Skip();
00221 }
00222
00223
00224 void GLWindow::onCommandEvent(wxCommandEvent & evt)
00225 {
00226 if (!module || !KERNEL || KERNEL->IsExiting())
00227 return;
00228
00229 switch (evt.GetEventType())
00230 {
00231 case Event::EVT_RENDER_FULLSCREEN_TOGGLE:
00232 if (evt.GetId() == int(GetID()))
00233 toggleFullscreen();
00234 break;
00235 case Event::EVT_RENDER_FULLSCREEN_SET:
00236 if (evt.GetId() == int(GetID()))
00237 setFullscreen(evt.GetInt() != 0);
00238 break;
00239 }
00240 }
00241
00242
00243 void GLWindow::Deinitialize()
00244 {
00245 wxCommandEvent ev = Event::GET_EVT_RENDER_WIN_CLOSED(int(windowID));
00246 KERNEL->GetMessageSink()->PostEvent(ev, true);
00248 if (module && glContext)
00249 {
00250 Scene * scene = KERNEL->sceneManager->GetScene(module->GetSceneID());
00251 if (scene)
00253 scene->Remove(module->GetCameraID());
00254 SetCurrent(*glContext);
00255 module->Deinitialize();
00256
00258 Parameter::ParameterIdentificator camPI(module->GetName(), wxT("cameraID"), module->GetID());
00259 wxCommandEvent ev1 = Event::GET_EVT_PARAM_SET(camPI, wxString::Format(wxT("%i"), NODE_ID_NONE));
00260 module->PostEvent(ev1, true);
00261 Parameter::ParameterIdentificator scenePI(module->GetName(), wxT("sceneID"), module->GetID());
00262 wxCommandEvent ev2 = Event::GET_EVT_PARAM_SET(scenePI, wxString::Format(wxT("%i"), SCENE_ID_NONE));
00263 module->PostEvent(ev2, true);
00264
00265 module = (RenderModule *)NULL;
00266 }
00267 }
00268
00269
00270 bool GLWindow::CreateGLContext()
00271 {
00272 SAFE_DELETE(glContext);
00273 glContext = new wxGLContext(this);
00274 return glContext != (wxGLContext *)NULL;
00275 }