VideoVis  0.9
Generates a volume visualisation of a video
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
glwidget.cpp
Go to the documentation of this file.
1 #define GL_GLEXT_PROTOTYPES
2 
3 #include <QtWidgets>
4 #include <QImage>
5 
6 
7 #include "glwidget.h"
8 
9 GLWidget::GLWidget(QWidget *parent) : QGLWidget(parent)
10 {
11  //Specifies an OpenGL 3.3 format using the Core profile
12  QGLFormat glFormat;
13  glFormat.setVersion(3, 3);
14  glFormat.setProfile(QGLFormat::CoreProfile);
15  glFormat.setSampleBuffers(true);
16  glFormat.setDepth(true);
17 
18  this->setFormat(glFormat);
19 
20  m_boxPosVBO = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
21  m_texCoordVBO = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
22  m_boxIBO = new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer);
23 
24  m_squarePosVBO = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
25  m_squareTexCoordVBO = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
26  m_squareIBO = new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer);
27 
28  m_volumeShader = NULL;
29  m_videoDiffShader = NULL;
30 
31  //p_cameraMatrix = new QMatrix4x4();
32  //p_viewMatrix = new QMatrix4x4();
33  //p_projectionMatrix = new QMatrix4x4();
34 
35  p_videoFrameToTextureLoader = NULL;
36 
37  m_drawMode = VV_DRAWMODE_VOLUME;
38 
39  m_frameOffset = 0;
40  m_cameraAngleSide = 0;
41  m_cameraAngleUp = 0;
42  m_cameraDistance = 10;
43 
44  m_cameraCenter = QVector3D(0, 0, 0);
45 
46  m_backgroundColor = QVector3D(1.0f, 1.0f, 1.0f);
47 
48  m_horseShowView = true;
49 
50  m_stepSize = 0.01;
51  m_boxSize = 4;
52 
53  p_videoBuffer = NULL;
54  p_videoDiffBuffer = NULL;
55  p_videoNDiffBuffer = NULL;
56  //pVideoDiffMeanBuffer = NULL;
57 
58  m_videoWidth = 4;
59  m_videoHeight = 3;
60  m_frameCount = 0;
61 
62  m_metric = VV_METRIC_NONE;
63 }
64 
66 {
67  delete m_boxPosVBO;
68  delete m_texCoordVBO;
69  delete m_boxIBO;
70  delete m_volumeShader;
71 
72  if (!p_videoFrameToTextureLoader)
73  delete p_videoFrameToTextureLoader;
74 }
75 
77  return QSize(400, 400);
78 }
79 QSize GLWidget::sizeHint() const {
80  return QSize(700, 700);
81 }
82 
83 
85 {
86  initializeOpenGLFunctions();
87 
88  glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) wglGetProcAddress("glGenVertexArrays");
89  glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) wglGetProcAddress("glBindVertexArray");
90  glTexImage3D = (PFNGLTEXIMAGE3DPROC) wglGetProcAddress("glTexImage3D");
91 
92  QGLFormat glFormat = QGLWidget::format();
93  if (!glFormat.sampleBuffers())
94  qWarning() << "Could not enable sample buffers";
95 
96  //Set the clear color to black
97  glClearColor(m_backgroundColor.x(), m_backgroundColor.y(), m_backgroundColor.z(), 1.0f);
98 
99  //Enable Z-Buffer
100  glEnable(GL_DEPTH_TEST);
101  glDepthFunc(GL_LEQUAL);
102 
103  //Prepare a complete shader program...
104  if (!loadShaders())
105  return;
106 
107  createBufferObjects();
108 
109  glGenTextures(1, &m_videoTexture);
110  glActiveTexture(GL_TEXTURE0);
111  glBindTexture(GL_TEXTURE_3D, m_videoTexture);
112 
113  // glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_R, GL_REPEAT);
114  glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
115  glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
116  glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
117  glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
118  glTexParameterf(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
119 
120  //Initialize the transfer function texture
121  glActiveTexture(GL_TEXTURE0 + 1);
122  glGenTextures(1, &m_transferTexture);
123  glBindTexture(GL_TEXTURE_1D, m_transferTexture);
124 
125  glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
126  glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
127  glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
128 
129  //Initalize the mean texture
130  glActiveTexture(GL_TEXTURE0 + 2);
131  glGenTextures(1, &m_meanTexture);
132  glBindTexture(GL_TEXTURE_1D, m_meanTexture);
133 
134  glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
135  glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
136  glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
137 
138  //Initalize the variance texture
139  glActiveTexture(GL_TEXTURE0 + 3);
140  glGenTextures(1, &m_transferTexture);
141  glBindTexture(GL_TEXTURE_1D, m_transferTexture);
142 
143  glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
144  glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
145  glTexParameterf(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
146 
147  setupCamera();
148  setupModelMatrix();
149 }
150 
152 {
153  // Clear the color and the depth buffer
154  glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
155 
156  switch (m_drawMode)
157  {
158  case VV_DRAWMODE_VOLUME:
159  m_volumeShader->bind();
160  m_volumeShader->setUniformValue("u_videoTexture", 0);
161  m_volumeShader->setUniformValue("u_transferTexture", 1);
162  m_volumeShader->setUniformValue("u_frameOffset", m_frameOffset);
163  m_volumeShader->setUniformValue("u_backColor", m_backgroundColor);
164  m_volumeShader->setUniformValue("u_MVPMatrix", m_projectionMatrix * m_viewMatrix * m_modelMatrix);
165  m_volumeShader->setUniformValue("u_MMatrix", m_modelMatrix);
166  m_volumeShader->setUniformValue("u_invM", m_modelMatrix.inverted());
167  m_volumeShader->setUniformValue("u_cameraPos", m_cameraPosition);
168  m_volumeShader->setUniformValue("u_horseShoeView", m_horseShowView);
169  m_volumeShader->setUniformValue("u_stepSize", m_stepSize);
170  m_volumeShader->setUniformValue("u_metric", m_metric);
171 
172  //Draw
173  glBindVertexArray(m_boxVAO);
174  glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, 0);
175  break;
176 
178  glBindVertexArray(m_squareVAO);
179  glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
180  break;
181  }
182 }
183 
184 void GLWidget::resizeGL(int width, int height)
185 {
186  m_projectionMatrix.setToIdentity();
187  m_projectionMatrix.perspective(60,(float) width / (float) height, (0.001f), 50.0f);
188 
189  // Set the viewport to window dimensions
190  glViewport(0, 0, width, height);
191 
192 }
193 
194 VFLResult GLWidget::openVideoFile(const QString &videoFilePath, int *hRes, int *vRes)
195 {
196  LPWSTR pVideoFilePath;
197  pVideoFilePath = new WCHAR[videoFilePath.length() + 1];
198  videoFilePath.toWCharArray(pVideoFilePath);
199  pVideoFilePath[videoFilePath.length()] = '\0';
200 
201  if (p_videoFrameToTextureLoader == NULL)
202  p_videoFrameToTextureLoader = new CVideoFrameToTextureLoader();
203 
204  VFLResult vr = p_videoFrameToTextureLoader->setVideoPath(pVideoFilePath);
205 
206  delete pVideoFilePath;
207 
208  if (vr != VFL_OK)
209  {
210  *hRes = 0;
211  *vRes = 0;
212  return vr;
213  }
214 
215  return p_videoFrameToTextureLoader->getVideoResolution(hRes, vRes);
216 }
217 
218 VFLResult GLWidget::loadVideoFile(int startFrame, int stepSize, int endFrame)
219 {
220  glActiveTexture(GL_TEXTURE0);
221  glBindTexture(GL_TEXTURE_3D, m_videoTexture);
222 
223  //p_videoFrameToTextureLoader->loadAllFramesIntoTexture(0, 0);
224 
225  if (p_videoBuffer != NULL)
226  delete p_videoBuffer;
227 
228  if (p_videoDiffBuffer != NULL)
229  {
230  delete p_videoDiffBuffer;
231  p_videoDiffBuffer = NULL;
232  }
233 
234  if (p_videoNDiffBuffer != NULL)
235  {
236  delete p_videoNDiffBuffer;
237  p_videoNDiffBuffer = NULL;
238  }
239 /*
240  if(pVideoDiffMeanBuffer != NULL)
241  {
242  delete pVideoDiffMeanBuffer;
243  pVideoDiffMeanBuffer = NULL;
244 
245  delete p_videoDiffDeviationBuffer;
246  }
247 */
248  VFLResult vr = p_videoFrameToTextureLoader->loadAllFramesIntoTexture(startFrame - 1,stepSize - 1, endFrame);
249 
250  if (vr != VFL_OK && vr != VFL_NO_MORE_FRAMES)
251  return vr;
252 
253  p_videoFrameToTextureLoader->getVideoBuffer(&p_videoBuffer);
254 
255  p_videoFrameToTextureLoader->getBufferFrameCount(&m_frameCount);
256  p_videoFrameToTextureLoader->getVideoResolution(&m_videoWidth, &m_videoHeight);
257 
258  setupModelMatrix();
259 
260  m_frameOffset = 0;
261 
262  VVMetric tempMetric = m_metric;
263  m_metric = VV_METRIC_NONE;
264 
265  setMetric(tempMetric);
266 
267  return VFL_OK;
268 }
269 
270 bool GLWidget::prepareShaderProgram(const QString &vertexShaderPath, const QString &fragmentShaderPath, QOpenGLShaderProgram **shader)
271 {
272  if (*shader != NULL)
273  delete *shader;
274 
275  *shader = new QOpenGLShaderProgram();
276 
277  // First we load and compile the vertex shader...
278  bool result = (*shader)->addShaderFromSourceFile( QOpenGLShader::Vertex, vertexShaderPath );
279  if ( !result )
280  qWarning() << m_volumeShader->log();
281 
282  // ...now the fragment shader...
283  result = (*shader)->addShaderFromSourceFile( QOpenGLShader::Fragment, fragmentShaderPath );
284  if ( !result )
285  qWarning() << m_volumeShader->log();
286 
287  // ...and finally we link them to resolve any references.
288  result = (*shader)->link();
289  if ( !result )
290  qWarning() << "Could not link shader program:" << m_volumeShader->log();
291 
292 
293  return result;
294 }
295 
296 void GLWidget::createBufferObjects()
297 {
298  float boxPos[] = { -1.0f, -1.0f, 1.0f,
299  1.0f, -1.0f, 1.0f,
300  -1.0f, 1.0f, 1.0f,
301  1.0f, 1.0f, 1.0f,
302 
303  -1.0f, -1.0f, -1.0f,
304  1.0f, -1.0f, -1.0f,
305  -1.0f, 1.0f, -1.0f,
306  1.0f, 1.0f, -1.0f
307  };
308 
309  float boxTexCoord[] = { 0.0f, 1.0f, 0.0f,
310  1.0f, 1.0f, 0.0f,
311  0.0f, 0.0f, 0.0f,
312  1.0f, 0.0f, 0.0f,
313 
314  0.0f, 1.0f, 1.0f,
315  1.0f, 1.0f, 1.0f,
316  0.0f, 0.0f, 1.0f,
317  1.0f, 0.0f, 1.0f
318  };
319 
320  GLubyte boxIndexes[] = {0, 1, 2, //+z
321  1, 3, 2,
322 
323  5, 4 ,7, //-z
324  4, 6, 7,
325 
326  2, 3, 6, //+y
327  3, 7 ,6,
328 
329  4 ,5, 0, //-y
330  5, 1, 0,
331 
332  1, 5, 3, //+x
333  5, 7, 3,
334 
335  4, 0, 6, //-x
336  0, 2, 6
337  };
338 
339  float squarePos[] = { -1.0f, -1.0f, 0.0f,
340  1.0f, -1.0f, 0.0f,
341  -1.0f, 1.0f, 0.0f,
342  1.0f, 1.0f, 0.0f,
343  };
344 
345  float squareTexCoord[] = { 0.0f, 1.0f,
346  1.0f, 1.0f,
347  0.0f, 0.0f,
348  1.0f, 0.0f
349  };
350 
351  GLubyte squareIndexes[] = { 0, 1, 2,
352  1, 3, 2
353  };
354 
355 
356 
357  //Bind the shader program
358  if (!m_volumeShader->bind())
359  {
360  qWarning() << "Could not bind shader program to context";
361  return;
362  }
363 
364  glGenVertexArrays(1, &m_boxVAO);
365  glBindVertexArray(m_boxVAO);
366 
367  m_boxPosVBO->create();
368  m_boxPosVBO->setUsagePattern(QOpenGLBuffer::StaticDraw);
369  m_boxPosVBO->bind();
370  m_boxPosVBO->allocate(boxPos, 8 * 3 * sizeof(float));
371 
372  //Enable the "vertex" attribute to bind in to our currently bound vertex buffer
373  m_volumeShader->setAttributeBuffer("pos", GL_FLOAT, 0, 3);
374 
375  m_texCoordVBO->create();
376  m_texCoordVBO->setUsagePattern(QOpenGLBuffer::StaticDraw);
377  m_texCoordVBO->bind();
378  m_texCoordVBO->allocate(boxTexCoord, 8 * 3 * sizeof(float));
379 
380  m_volumeShader->setAttributeBuffer("texCoord", GL_FLOAT, 0, 3);
381 
382  m_boxIBO->create();
383  m_boxIBO->setUsagePattern(QOpenGLBuffer::StaticDraw);
384  m_boxIBO->bind();
385  m_boxIBO->allocate(boxIndexes, 36 * sizeof(GLubyte));
386 
387  m_volumeShader->enableAttributeArray("pos");
388  m_volumeShader->enableAttributeArray("texCoord");
389 
390 
391  glGenVertexArrays(1, &m_squareVAO);
392  glBindVertexArray(m_squareVAO);
393 
394  m_squarePosVBO->create();
395  m_squarePosVBO->setUsagePattern(QOpenGLBuffer::StaticDraw);
396  m_squarePosVBO->bind();
397  m_squarePosVBO->allocate(squarePos, 4 * 3 * sizeof(float));
398 
399  //Enable the "vertex" attribute to bind in to our currently bound vertex buffer
400  m_videoDiffShader->setAttributeBuffer("pos", GL_FLOAT, 0, 3);
401 
402  m_squareTexCoordVBO->create();
403  m_squareTexCoordVBO->setUsagePattern(QOpenGLBuffer::StaticDraw);
404  m_squareTexCoordVBO->bind();
405  m_squareTexCoordVBO->allocate(squareTexCoord, 4 * 3 * sizeof(float));
406 
407  m_videoDiffShader->setAttributeBuffer("texCoord", GL_FLOAT, 0, 2);
408 
409  m_squareIBO->create();
410  m_squareIBO->setUsagePattern(QOpenGLBuffer::StaticDraw);
411  m_squareIBO->bind();
412  m_squareIBO->allocate(squareIndexes, 6 * sizeof(GLubyte));
413 
414  m_videoDiffShader->enableAttributeArray("pos");
415  m_videoDiffShader->enableAttributeArray("texCoord");
416 }
417 
419 {
420  if (p_videoFrameToTextureLoader == NULL)
421  return 0;
422 
423  int frameCount = 0;
424 
425  p_videoFrameToTextureLoader->getBufferFrameCount(&frameCount);
426 
427  return frameCount;
428 }
429 
430 void GLWidget::setFrameOffset(int frameOffset)
431 {
432  m_frameOffset = (float)frameOffset/(float)m_frameCount; //((float)frameOffset + 0.5)/(float)getFrameCount();
433  m_volumeShader->setUniformValue("u_frameOffset", m_frameOffset);
434  updateGL();
435 }
436 
437 void GLWidget::setStyle(bool horseShoeView)
438 {
439  m_horseShowView = horseShoeView;
440  setupModelMatrix();
441  updateGL();
442 }
443 
444 void GLWidget::setupCamera()
445 {
446  QMatrix4x4 cameraRotation, cameraTransformation;
447 
448  //cameraPositioning.translate(m_cameraCenter);
449 
450  cameraTransformation.translate(0, 0, m_cameraDistance);
451 
452  cameraRotation.rotate(m_cameraAngleSide, 0, 1, 0);
453  cameraRotation.rotate(m_cameraAngleUp, 1, 0, 0);
454 
455  QVector3D cameraUpDirection = cameraRotation * QVector3D(0, 1, 0);
456 
457  cameraTransformation = cameraRotation * cameraTransformation;
458 
459  QMatrix4x4 cameraPositioning;
460 
461  cameraPositioning.translate(m_cameraCenter.x(), m_cameraCenter.y(), m_cameraCenter.z());
462 
463  cameraTransformation = cameraPositioning * cameraTransformation;
464 
465  m_cameraPosition = cameraTransformation * QVector3D(0, 0, 0);
466  // m_cameraPosition = cameraPositioning * m_cameraPosition;
467 
468 
469  m_viewMatrix.setToIdentity();
470  m_viewMatrix.lookAt(m_cameraPosition, m_cameraCenter, cameraUpDirection);
471 }
472 
473 void GLWidget::setupModelMatrix()
474 {
475  float aspectRatio = (float) m_videoHeight / (float) m_videoWidth;
476 
477  m_modelMatrix.setToIdentity();
478 
479  if (m_horseShowView)
480  m_modelMatrix.scale(4, aspectRatio , 2);
481  else
482  m_modelMatrix.scale(1, aspectRatio, m_boxSize);
483 }
484 
485 void GLWidget::calculateVideoDiffBuffer(bool normalized)
486 {
487  QOpenGLFramebufferObject videoDiffFBO(m_videoWidth, m_videoHeight, QOpenGLFramebufferObject::NoAttachment, GL_TEXTURE_2D, GL_RGBA);
488 
489  glViewport(0, 0, m_videoWidth, m_videoHeight);
490 
491  bool test = videoDiffFBO.bind();
492 
493  if (test != true)
494  return;
495 
496  PBYTE *resultBuffer = NULL;
497 
498  m_videoDiffShader->bind();
499 
500  m_videoDiffShader->setUniformValue("u_videoTexture", 0);
501  m_videoDiffShader->setUniformValue("u_meanTexture", 2);
502  m_videoDiffShader->setUniformValue("u_devTexture", 3);
503  m_videoDiffShader->setUniformValue("u_frameCount", m_frameCount);
504  m_videoDiffShader->setUniformValue("u_nTrans", normalized);
505 
506  if (normalized)
507  {
508  calculateMeanAndStdDev();
509  resultBuffer = &p_videoNDiffBuffer;
510  }
511  else
512  {
513  resultBuffer = &p_videoDiffBuffer;
514  }
515 
516 
517  m_drawMode = VV_DRAWMODE_VIDEODIFF;
518 
519  int frameSize = m_videoWidth * m_videoHeight * 4;
520 
521  if (*resultBuffer != NULL)
522  delete *resultBuffer;
523 
524  *resultBuffer = new BYTE[(long) frameSize * (long) m_frameCount];
525 
526  for (int frameCounter = 0; frameCounter < m_frameCount; frameCounter++)
527  {
528  m_videoDiffShader->setUniformValue("u_currentFrame", frameCounter);
529  paintGL();
530 
531  QImage image = videoDiffFBO.toImage();
532 
533  PBYTE imageData = (PBYTE) image.constBits();
534 
535  long offset = (long) frameCounter * (long) frameSize;
536 
537  for (int byteCounter = 0; byteCounter < frameSize; byteCounter++)
538  {
539  (*resultBuffer)[offset + byteCounter] = imageData[byteCounter];
540  }
541  }
542 
543  glViewport(0, 0, size().width(), size().height());
544 
545  m_drawMode = VV_DRAWMODE_VOLUME;
546  videoDiffFBO.release();
547 }
548 
549 void GLWidget::calculateMeanAndStdDev()
550 {
551  GLfloat* pVideoDiffMeanBuffer = new GLfloat[m_frameCount];
552  GLfloat* pVideoDiffDeviationBuffer = new GLfloat[m_frameCount];
553 
554  long byteCount = m_videoWidth * m_videoHeight;
555  long sampleSize = byteCount * 4;
556 
557  for (int frameCounter = 0; frameCounter < m_frameCount; frameCounter++)
558  {
559  double *YValues = new double[byteCount];
560 
561  long byteSum = 0;
562  long offset = sampleSize * frameCounter;
563 
564  for (long byteCounter = 0; byteCounter < byteCount; byteCounter++)
565  {
566  YValues[byteCounter] = (double) p_videoBuffer[offset + byteCounter * 4 + 2] * 0.299 +
567  (double) p_videoBuffer[offset + byteCounter * 4 + 1] * 0.587 +
568  (double) p_videoBuffer[offset + byteCounter * 4] * 0.144;
569 
570  byteSum += YValues[byteCounter];
571  }
572 
573  double meanValue = (double)byteSum / (double)byteCount;
574 
575  double sum = 0;
576 
577  for (long byteCounter = 0; byteCounter < byteCount; byteCounter++)
578  {
579  sum += pow((double) YValues[byteCounter] - meanValue, 2);
580  }
581 
582  double standardDeviation = sqrt(sum / (double) byteCount);
583 
584  pVideoDiffMeanBuffer[frameCounter] = meanValue / 255.0;
585  pVideoDiffDeviationBuffer[frameCounter] = standardDeviation / 255.0;
586 
587  delete YValues;
588  }
589 
590  glActiveTexture(GL_TEXTURE0 + 2);
591  glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB32F, m_frameCount, 0, GL_RED, GL_FLOAT, pVideoDiffMeanBuffer);
592 
593  glActiveTexture(GL_TEXTURE0 + 3);
594  glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB32F, m_frameCount, 0, GL_RED, GL_FLOAT, pVideoDiffDeviationBuffer);
595 
596  delete pVideoDiffMeanBuffer;
597  delete pVideoDiffDeviationBuffer;
598 }
599 
600 bool GLWidget::loadShaders()
601 {
602  if (!prepareShaderProgram(":/ShaderFiles/volume.vert", ":/ShaderFiles/volume.frag", &m_volumeShader))
603  return false;
604 
605  if (!prepareShaderProgram(":/ShaderFiles/videoDiff.vert", ":/ShaderFiles/videoDiff.frag", &m_videoDiffShader))
606  return false;
607 
608  return true;
609 }
610 
611 void GLWidget::mousePressEvent(QMouseEvent *event)
612 {
613  if (event->buttons() & Qt::RightButton || event->buttons() & Qt::MidButton)
614  {
615  m_oldMousePos = mapFromGlobal(QCursor::pos());
616  setCursor(Qt::BlankCursor);
617  }
618 
619 
620 }
621 
622 void GLWidget::mouseReleaseEvent(QMouseEvent *event)
623 {
624  //if (event->buttons() & Qt::RightButton)
625  //{
626  setCursor(Qt::ArrowCursor);
627  //}
628 }
629 
630 void GLWidget::wheelEvent(QWheelEvent *event)
631 {
632  m_cameraDistance += (float)event->delta() / (float) 100;
633  setupCamera();
634 
635  updateGL();
636 }
637 
638 void GLWidget::mouseMoveEvent(QMouseEvent *event)
639 {
640  //DEBUG
641  //qDebug() << dx << " " << dy;
642  if(event->buttons() & Qt::RightButton || event->buttons() & Qt::MidButton)
643  {
644  QPoint mousePos = mapFromGlobal(QCursor::pos());
645  GLfloat dx = GLfloat(mousePos.x() - m_oldMousePos.x()) / width();
646  GLfloat dy = GLfloat(mousePos.y() - m_oldMousePos.y()) / height();
647 
648  if (event->buttons() & Qt::RightButton)
649  {
650  m_cameraAngleSide -= dx * 180;
651  m_cameraAngleUp -= dy * 180;
652 
653  if (m_cameraAngleSide < 0)
654  m_cameraAngleSide = 360 + m_cameraAngleSide;
655 
656  if (m_cameraAngleSide > 360)
657  m_cameraAngleSide = m_cameraAngleSide - 360;
658 
659  if (m_cameraAngleUp < -90)
660  m_cameraAngleUp = -90;
661 
662  if (m_cameraAngleUp > 90)
663  m_cameraAngleUp = 90;
664  }
665 
666  if (event->buttons() & Qt::MidButton)
667  {
668  QMatrix4x4 cameraTransformation;
669 
670  QVector3D cameraMotion;
671  cameraMotion.setX(- dx * 50);
672  cameraMotion.setY(dy * 50);
673 
674  cameraTransformation.rotate(m_cameraAngleSide, 0, 1, 0);
675  cameraTransformation.rotate(m_cameraAngleUp, 1, 0, 0);
676 
677  cameraMotion = cameraTransformation * cameraMotion;
678 
679  QMatrix4x4 cameraPositioning;
680 
681  cameraPositioning.translate(cameraMotion);
682 
683  m_cameraCenter = cameraPositioning * m_cameraCenter;
684 
685  //m_cameraCenter.setX(m_cameraCenter.x() - );
686  // m_cameraCenter.setY(m_cameraCenter.y() - dy * 50);
687  }
688 
689  QCursor::setPos(mapToGlobal(m_oldMousePos));
690 
691  setupCamera();
692  updateGL();
693  }
694 }
695 
696 void GLWidget::setStepSize(float stepSize)
697 {
698  m_stepSize = stepSize;
699  updateGL();
700 }
701 
702 void GLWidget::setBoxSize(int boxSize)
703 {
704  m_boxSize = boxSize;
705  setupModelMatrix();
706  updateGL();
707 }
708 
710 {
711  VVMetric old_metric = m_metric;
712 
713  m_metric = metric;
714 
715  switch (metric)
716  {
717  case VV_METRIC_NONE:
718  glActiveTexture(GL_TEXTURE0);
719  glBindTexture(GL_TEXTURE_3D, m_videoTexture);
720  glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, m_videoWidth, m_videoHeight, m_frameCount, 0, GL_BGRA, GL_UNSIGNED_BYTE, p_videoBuffer);
721  updateGL();
722  break;
723 
724  case VV_METRIC_IQDIF:
725  case VV_METRIC_YDIF:
726  case VV_METRIC_YMSE:
727  if (p_videoDiffBuffer == NULL)
728  {
729  if (old_metric != VV_METRIC_NONE)
730  {
731  glActiveTexture(GL_TEXTURE0);
732  glBindTexture(GL_TEXTURE_3D, m_videoTexture);
733  glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, m_videoWidth, m_videoHeight, m_frameCount, 0, GL_BGRA, GL_UNSIGNED_BYTE, p_videoBuffer);
734  }
735  calculateVideoDiffBuffer(false);
736  }
737 
738  if (old_metric == VV_METRIC_NONE || old_metric == VV_METRIC_YNDIF || old_metric == VV_METRIC_YNMSE)
739  {
740  glActiveTexture(GL_TEXTURE0);
741  glBindTexture(GL_TEXTURE_3D, m_videoTexture);
742  glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, m_videoWidth, m_videoHeight, m_frameCount, 0, GL_BGRA, GL_UNSIGNED_BYTE, p_videoDiffBuffer);
743  }
744  updateGL();
745  break;
746 
747  case VV_METRIC_YNDIF:
748  case VV_METRIC_YNMSE:
749  if (p_videoNDiffBuffer == NULL)
750  {
751  if (old_metric != VV_METRIC_NONE)
752  {
753  glActiveTexture(GL_TEXTURE0);
754  glBindTexture(GL_TEXTURE_3D, m_videoTexture);
755  glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, m_videoWidth, m_videoHeight, m_frameCount, 0, GL_BGRA, GL_UNSIGNED_BYTE, p_videoBuffer);
756  }
757  calculateVideoDiffBuffer(true);
758  }
759 
760  if (old_metric == VV_METRIC_NONE || old_metric == VV_METRIC_IQDIF || old_metric == VV_METRIC_YDIF || old_metric == VV_METRIC_YMSE)
761  {
762  glActiveTexture(GL_TEXTURE0);
763  glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, m_videoWidth, m_videoHeight, m_frameCount, 0, GL_BGRA, GL_UNSIGNED_BYTE, p_videoNDiffBuffer);
764  }
765  updateGL();
766  break;
767 
768  }
769 }
770 
771 void GLWidget::setTransferFunction(GLfloat *tfArray, int arraySize)
772 {
773  glActiveTexture(GL_TEXTURE0 + 1);
774  glBindTexture(GL_TEXTURE_1D, m_transferTexture);
775  glTexImage1D(GL_TEXTURE_1D, 0, GL_RGBA32F, arraySize, 0, GL_RGBA, GL_FLOAT, tfArray);
776 
777  delete tfArray;
778 
779  updateGL();
780  //p_transferFunction = value;
781 }