1 //
2 // MotionBlurSimWindow.cpp
3 // dart
4 //
5 // Created by Dong Xu on 1/22/17.
6 //
7 //
8
9 /////////////////////////////////////////////////////////////////////////
10 // OpenGL Motion blur require the Accumulate function of OpenGL
11 // To intergrate this class into the engine
12 // Change line 86 of dart/gui/glut/Window.cpp
13 // From glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA |
14 // GLUT_MULTISAMPLE); to glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE |
15 // GLUT_RGBA | GLUT_MULTISAMPLE | GLUT_ACCUM);
16 /////////////////////////////////////////////////////////////////////////
17
18 #include "dart/gui/glut/MotionBlurSimWindow.hpp"
19
20 #include "dart/constraint/ConstraintSolver.hpp"
21 #include "dart/gui/GLFuncs.hpp"
22 #include "dart/gui/glut/LoadGlut.hpp"
23
24 namespace dart {
25 namespace gui {
26 namespace glut {
27
28 //==============================================================================
MotionBlurSimWindow()29 MotionBlurSimWindow::MotionBlurSimWindow() : SimWindow()
30 {
31 mMotionBlurFrequency = 1;
32 }
33
34 //==============================================================================
~MotionBlurSimWindow()35 MotionBlurSimWindow::~MotionBlurSimWindow()
36 {
37 // Do nothing
38 }
39
40 //==============================================================================
setMotionBlurQuality(int _val)41 void MotionBlurSimWindow::setMotionBlurQuality(int _val)
42 {
43 int numIter = mDisplayTimeout / (mWorld->getTimeStep() * 1000);
44 if (_val < 0)
45 {
46 std::cout << "setMotionBlurQuality: input should be an int between 0-5, "
47 "Regard as 0"
48 << std::endl;
49 std::cout << "0: No motion blur, 5: Motion blur with highest quality"
50 << std::endl;
51 mMotionBlurFrequency = numIter;
52 }
53 else if (_val > 5)
54 {
55 std::cout << "setMotionBlurQuality: input should be an int between 0-5, "
56 "Regard as 5"
57 << std::endl;
58 std::cout << "0: No motion blur, 5: Motion blur with highest quality"
59 << std::endl;
60 mMotionBlurFrequency = 1;
61 }
62 else if (_val == 0)
63 mMotionBlurFrequency = mDisplayTimeout / (mWorld->getTimeStep() * 1000);
64 else if (_val == 1)
65 mMotionBlurFrequency = std::min(numIter, 16);
66 else if (_val == 2)
67 mMotionBlurFrequency = std::min(numIter, 8);
68 else if (_val == 3)
69 mMotionBlurFrequency = std::min(numIter, 4);
70 else if (_val == 4)
71 mMotionBlurFrequency = std::min(numIter, 2);
72 else // _val == 5
73 mMotionBlurFrequency = 1;
74 }
75
76 //==============================================================================
render()77 void MotionBlurSimWindow::render()
78 {
79 int numIter = mDisplayTimeout / (mWorld->getTimeStep() * 1000);
80 int numMotionBlurFrames = ceil(
81 floor(mDisplayTimeout)
82 / (mWorld->getTimeStep() * 1000 * mMotionBlurFrequency));
83 if (!mPlay && mSimulating)
84 {
85 for (int i = 0; i < numIter; i += mMotionBlurFrequency)
86 {
87 for (int j = 0; j < mMotionBlurFrequency; j++)
88 {
89 if (i + j < numIter)
90 {
91 timeStepping();
92 mWorld->bake();
93 }
94 }
95
96 // Update the camera position before every draw
97 glMatrixMode(GL_PROJECTION);
98 glLoadIdentity();
99 gluPerspective(
100 mPersp,
101 static_cast<double>(mWinWidth) / static_cast<double>(mWinHeight),
102 0.1,
103 10.0);
104
105 glMatrixMode(GL_MODELVIEW);
106 glLoadIdentity();
107 gluLookAt(
108 mEye[0], mEye[1], mEye[2], 0.0, 0.0, -1.0, mUp[0], mUp[1], mUp[2]);
109 initGL();
110
111 mTrackBall.applyGLRotation();
112
113 // Draw world origin indicator
114 if (!mCapture)
115 {
116 glEnable(GL_DEPTH_TEST);
117 glDisable(GL_TEXTURE_2D);
118 glDisable(GL_LIGHTING);
119 glLineWidth(2.0);
120 if (mRotate || mTranslate || mZooming)
121 {
122 glColor3f(1.0f, 0.0f, 0.0f);
123 glBegin(GL_LINES);
124 glVertex3f(-0.1f, 0.0f, -0.0f);
125 glVertex3f(0.15f, 0.0f, -0.0f);
126 glEnd();
127
128 glColor3f(0.0f, 1.0f, 0.0f);
129 glBegin(GL_LINES);
130 glVertex3f(0.0f, -0.1f, 0.0f);
131 glVertex3f(0.0f, 0.15f, 0.0f);
132 glEnd();
133
134 glColor3f(0.0f, 0.0f, 1.0f);
135 glBegin(GL_LINES);
136 glVertex3f(0.0f, 0.0f, -0.1f);
137 glVertex3f(0.0f, 0.0f, 0.15f);
138 glEnd();
139 }
140 }
141
142 glScalef(mZoom, mZoom, mZoom);
143 glTranslatef(mTrans[0] * 0.001, mTrans[1] * 0.001, mTrans[2] * 0.001);
144
145 initLights();
146 draw();
147
148 if (i == 0)
149 {
150 // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
151 glAccum(GL_LOAD, 1 / float(numMotionBlurFrames));
152 }
153 else
154 {
155 glAccum(GL_ACCUM, 1 / float(numMotionBlurFrames));
156 }
157 } // for loop
158 } // if simulating
159 else if (mWorld->getRecording()->getNumFrames() == 0)
160 {
161 glMatrixMode(GL_PROJECTION);
162 glLoadIdentity();
163 gluPerspective(
164 mPersp,
165 static_cast<double>(mWinWidth) / static_cast<double>(mWinHeight),
166 0.1,
167 10.0);
168
169 glMatrixMode(GL_MODELVIEW);
170 glLoadIdentity();
171 gluLookAt(
172 mEye[0], mEye[1], mEye[2], 0.0, 0.0, -1.0, mUp[0], mUp[1], mUp[2]);
173 initGL();
174
175 mTrackBall.applyGLRotation();
176
177 // Draw world origin indicator
178 if (!mCapture)
179 {
180 glEnable(GL_DEPTH_TEST);
181 glDisable(GL_TEXTURE_2D);
182 glDisable(GL_LIGHTING);
183 glLineWidth(2.0);
184 if (mRotate || mTranslate || mZooming)
185 {
186 glColor3f(1.0f, 0.0f, 0.0f);
187 glBegin(GL_LINES);
188 glVertex3f(-0.1f, 0.0f, -0.0f);
189 glVertex3f(0.15f, 0.0f, -0.0f);
190 glEnd();
191
192 glColor3f(0.0f, 1.0f, 0.0f);
193 glBegin(GL_LINES);
194 glVertex3f(0.0f, -0.1f, 0.0f);
195 glVertex3f(0.0f, 0.15f, 0.0f);
196 glEnd();
197
198 glColor3f(0.0f, 0.0f, 1.0f);
199 glBegin(GL_LINES);
200 glVertex3f(0.0f, 0.0f, -0.1f);
201 glVertex3f(0.0f, 0.0f, 0.15f);
202 glEnd();
203 }
204 }
205
206 glScalef(mZoom, mZoom, mZoom);
207 glTranslatef(mTrans[0] * 0.001, mTrans[1] * 0.001, mTrans[2] * 0.001);
208
209 initLights();
210 draw();
211
212 glAccum(GL_LOAD, 1.0f);
213 }
214
215 // Draw trackball indicator
216 // Currently, trackball is not counted into the motion blur
217 if (mRotate && !mCapture)
218 mTrackBall.draw(mWinWidth, mWinHeight);
219
220 // Clear an return the buffer
221 glAccum(GL_RETURN, 1.0f);
222 glutSwapBuffers();
223
224 if (mCapture)
225 screenshot();
226 }
227
228 //==============================================================================
displayTimer(int _val)229 void MotionBlurSimWindow::displayTimer(int _val)
230 {
231 if (mPlay)
232 {
233 mPlayFrame += 16;
234 if (mPlayFrame >= mWorld->getRecording()->getNumFrames())
235 mPlayFrame = 0;
236 }
237 glutPostRedisplay();
238 glutTimerFunc(mDisplayTimeout, refreshTimer, _val);
239 }
240
241 } // namespace glut
242 } // namespace gui
243 } // namespace dart
244