1 #define GL_GLEXT_PROTOTYPES
13 glFormat.setVersion(3, 3);
14 glFormat.setProfile(QGLFormat::CoreProfile);
15 glFormat.setSampleBuffers(
true);
16 glFormat.setDepth(
true);
18 this->setFormat(glFormat);
20 m_boxPosVBO =
new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
21 m_texCoordVBO =
new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
22 m_boxIBO =
new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer);
24 m_squarePosVBO =
new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
25 m_squareTexCoordVBO =
new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer);
26 m_squareIBO =
new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer);
28 m_volumeShader = NULL;
29 m_videoDiffShader = NULL;
35 p_videoFrameToTextureLoader = NULL;
40 m_cameraAngleSide = 0;
42 m_cameraDistance = 10;
44 m_cameraCenter = QVector3D(0, 0, 0);
46 m_backgroundColor = QVector3D(1.0f, 1.0f, 1.0f);
48 m_horseShowView =
true;
54 p_videoDiffBuffer = NULL;
55 p_videoNDiffBuffer = NULL;
70 delete m_volumeShader;
72 if (!p_videoFrameToTextureLoader)
73 delete p_videoFrameToTextureLoader;
77 return QSize(400, 400);
80 return QSize(700, 700);
86 initializeOpenGLFunctions();
88 glGenVertexArrays = (PFNGLGENVERTEXARRAYSPROC) wglGetProcAddress(
"glGenVertexArrays");
89 glBindVertexArray = (PFNGLBINDVERTEXARRAYPROC) wglGetProcAddress(
"glBindVertexArray");
90 glTexImage3D = (PFNGLTEXIMAGE3DPROC) wglGetProcAddress(
"glTexImage3D");
92 QGLFormat glFormat = QGLWidget::format();
93 if (!glFormat.sampleBuffers())
94 qWarning() <<
"Could not enable sample buffers";
97 glClearColor(m_backgroundColor.x(), m_backgroundColor.y(), m_backgroundColor.z(), 1.0f);
100 glEnable(GL_DEPTH_TEST);
101 glDepthFunc(GL_LEQUAL);
107 createBufferObjects();
109 glGenTextures(1, &m_videoTexture);
110 glActiveTexture(GL_TEXTURE0);
111 glBindTexture(GL_TEXTURE_3D, m_videoTexture);
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);
121 glActiveTexture(GL_TEXTURE0 + 1);
122 glGenTextures(1, &m_transferTexture);
123 glBindTexture(GL_TEXTURE_1D, m_transferTexture);
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);
130 glActiveTexture(GL_TEXTURE0 + 2);
131 glGenTextures(1, &m_meanTexture);
132 glBindTexture(GL_TEXTURE_1D, m_meanTexture);
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);
139 glActiveTexture(GL_TEXTURE0 + 3);
140 glGenTextures(1, &m_transferTexture);
141 glBindTexture(GL_TEXTURE_1D, m_transferTexture);
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);
154 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
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);
174 glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_BYTE, 0);
179 glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, 0);
186 m_projectionMatrix.setToIdentity();
187 m_projectionMatrix.perspective(60,(
float) width / (
float) height, (0.001f), 50.0f);
190 glViewport(0, 0, width, height);
196 LPWSTR pVideoFilePath;
197 pVideoFilePath =
new WCHAR[videoFilePath.length() + 1];
198 videoFilePath.toWCharArray(pVideoFilePath);
199 pVideoFilePath[videoFilePath.length()] =
'\0';
201 if (p_videoFrameToTextureLoader == NULL)
206 delete pVideoFilePath;
220 glActiveTexture(GL_TEXTURE0);
221 glBindTexture(GL_TEXTURE_3D, m_videoTexture);
225 if (p_videoBuffer != NULL)
226 delete p_videoBuffer;
228 if (p_videoDiffBuffer != NULL)
230 delete p_videoDiffBuffer;
231 p_videoDiffBuffer = NULL;
234 if (p_videoNDiffBuffer != NULL)
236 delete p_videoNDiffBuffer;
237 p_videoNDiffBuffer = NULL;
270 bool GLWidget::prepareShaderProgram(
const QString &vertexShaderPath,
const QString &fragmentShaderPath, QOpenGLShaderProgram **shader)
275 *shader =
new QOpenGLShaderProgram();
278 bool result = (*shader)->addShaderFromSourceFile( QOpenGLShader::Vertex, vertexShaderPath );
280 qWarning() << m_volumeShader->log();
283 result = (*shader)->addShaderFromSourceFile( QOpenGLShader::Fragment, fragmentShaderPath );
285 qWarning() << m_volumeShader->log();
288 result = (*shader)->link();
290 qWarning() <<
"Could not link shader program:" << m_volumeShader->log();
296 void GLWidget::createBufferObjects()
298 float boxPos[] = { -1.0f, -1.0f, 1.0f,
309 float boxTexCoord[] = { 0.0f, 1.0f, 0.0f,
320 GLubyte boxIndexes[] = {0, 1, 2,
339 float squarePos[] = { -1.0f, -1.0f, 0.0f,
345 float squareTexCoord[] = { 0.0f, 1.0f,
351 GLubyte squareIndexes[] = { 0, 1, 2,
358 if (!m_volumeShader->bind())
360 qWarning() <<
"Could not bind shader program to context";
367 m_boxPosVBO->create();
368 m_boxPosVBO->setUsagePattern(QOpenGLBuffer::StaticDraw);
370 m_boxPosVBO->allocate(boxPos, 8 * 3 *
sizeof(
float));
373 m_volumeShader->setAttributeBuffer(
"pos", GL_FLOAT, 0, 3);
375 m_texCoordVBO->create();
376 m_texCoordVBO->setUsagePattern(QOpenGLBuffer::StaticDraw);
377 m_texCoordVBO->bind();
378 m_texCoordVBO->allocate(boxTexCoord, 8 * 3 *
sizeof(
float));
380 m_volumeShader->setAttributeBuffer(
"texCoord", GL_FLOAT, 0, 3);
383 m_boxIBO->setUsagePattern(QOpenGLBuffer::StaticDraw);
385 m_boxIBO->allocate(boxIndexes, 36 *
sizeof(GLubyte));
387 m_volumeShader->enableAttributeArray(
"pos");
388 m_volumeShader->enableAttributeArray(
"texCoord");
394 m_squarePosVBO->create();
395 m_squarePosVBO->setUsagePattern(QOpenGLBuffer::StaticDraw);
396 m_squarePosVBO->bind();
397 m_squarePosVBO->allocate(squarePos, 4 * 3 *
sizeof(
float));
400 m_videoDiffShader->setAttributeBuffer(
"pos", GL_FLOAT, 0, 3);
402 m_squareTexCoordVBO->create();
403 m_squareTexCoordVBO->setUsagePattern(QOpenGLBuffer::StaticDraw);
404 m_squareTexCoordVBO->bind();
405 m_squareTexCoordVBO->allocate(squareTexCoord, 4 * 3 *
sizeof(
float));
407 m_videoDiffShader->setAttributeBuffer(
"texCoord", GL_FLOAT, 0, 2);
409 m_squareIBO->create();
410 m_squareIBO->setUsagePattern(QOpenGLBuffer::StaticDraw);
412 m_squareIBO->allocate(squareIndexes, 6 *
sizeof(GLubyte));
414 m_videoDiffShader->enableAttributeArray(
"pos");
415 m_videoDiffShader->enableAttributeArray(
"texCoord");
420 if (p_videoFrameToTextureLoader == NULL)
432 m_frameOffset = (float)frameOffset/(
float)m_frameCount;
433 m_volumeShader->setUniformValue(
"u_frameOffset", m_frameOffset);
439 m_horseShowView = horseShoeView;
444 void GLWidget::setupCamera()
446 QMatrix4x4 cameraRotation, cameraTransformation;
450 cameraTransformation.translate(0, 0, m_cameraDistance);
452 cameraRotation.rotate(m_cameraAngleSide, 0, 1, 0);
453 cameraRotation.rotate(m_cameraAngleUp, 1, 0, 0);
455 QVector3D cameraUpDirection = cameraRotation * QVector3D(0, 1, 0);
457 cameraTransformation = cameraRotation * cameraTransformation;
459 QMatrix4x4 cameraPositioning;
461 cameraPositioning.translate(m_cameraCenter.x(), m_cameraCenter.y(), m_cameraCenter.z());
463 cameraTransformation = cameraPositioning * cameraTransformation;
465 m_cameraPosition = cameraTransformation * QVector3D(0, 0, 0);
469 m_viewMatrix.setToIdentity();
470 m_viewMatrix.lookAt(m_cameraPosition, m_cameraCenter, cameraUpDirection);
473 void GLWidget::setupModelMatrix()
475 float aspectRatio = (float) m_videoHeight / (
float) m_videoWidth;
477 m_modelMatrix.setToIdentity();
480 m_modelMatrix.scale(4, aspectRatio , 2);
482 m_modelMatrix.scale(1, aspectRatio, m_boxSize);
485 void GLWidget::calculateVideoDiffBuffer(
bool normalized)
487 QOpenGLFramebufferObject videoDiffFBO(m_videoWidth, m_videoHeight, QOpenGLFramebufferObject::NoAttachment, GL_TEXTURE_2D, GL_RGBA);
489 glViewport(0, 0, m_videoWidth, m_videoHeight);
491 bool test = videoDiffFBO.bind();
496 PBYTE *resultBuffer = NULL;
498 m_videoDiffShader->bind();
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);
508 calculateMeanAndStdDev();
509 resultBuffer = &p_videoNDiffBuffer;
513 resultBuffer = &p_videoDiffBuffer;
519 int frameSize = m_videoWidth * m_videoHeight * 4;
521 if (*resultBuffer != NULL)
522 delete *resultBuffer;
524 *resultBuffer =
new BYTE[(long) frameSize * (
long) m_frameCount];
526 for (
int frameCounter = 0; frameCounter < m_frameCount; frameCounter++)
528 m_videoDiffShader->setUniformValue(
"u_currentFrame", frameCounter);
531 QImage image = videoDiffFBO.toImage();
533 PBYTE imageData = (PBYTE) image.constBits();
535 long offset = (long) frameCounter * (
long) frameSize;
537 for (
int byteCounter = 0; byteCounter < frameSize; byteCounter++)
539 (*resultBuffer)[offset + byteCounter] = imageData[byteCounter];
543 glViewport(0, 0, size().width(), size().height());
546 videoDiffFBO.release();
549 void GLWidget::calculateMeanAndStdDev()
551 GLfloat* pVideoDiffMeanBuffer =
new GLfloat[m_frameCount];
552 GLfloat* pVideoDiffDeviationBuffer =
new GLfloat[m_frameCount];
554 long byteCount = m_videoWidth * m_videoHeight;
555 long sampleSize = byteCount * 4;
557 for (
int frameCounter = 0; frameCounter < m_frameCount; frameCounter++)
559 double *YValues =
new double[byteCount];
562 long offset = sampleSize * frameCounter;
564 for (
long byteCounter = 0; byteCounter < byteCount; byteCounter++)
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;
570 byteSum += YValues[byteCounter];
573 double meanValue = (double)byteSum / (
double)byteCount;
577 for (
long byteCounter = 0; byteCounter < byteCount; byteCounter++)
579 sum += pow((
double) YValues[byteCounter] - meanValue, 2);
582 double standardDeviation = sqrt(sum / (
double) byteCount);
584 pVideoDiffMeanBuffer[frameCounter] = meanValue / 255.0;
585 pVideoDiffDeviationBuffer[frameCounter] = standardDeviation / 255.0;
590 glActiveTexture(GL_TEXTURE0 + 2);
591 glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB32F, m_frameCount, 0, GL_RED, GL_FLOAT, pVideoDiffMeanBuffer);
593 glActiveTexture(GL_TEXTURE0 + 3);
594 glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB32F, m_frameCount, 0, GL_RED, GL_FLOAT, pVideoDiffDeviationBuffer);
596 delete pVideoDiffMeanBuffer;
597 delete pVideoDiffDeviationBuffer;
600 bool GLWidget::loadShaders()
602 if (!prepareShaderProgram(
":/ShaderFiles/volume.vert",
":/ShaderFiles/volume.frag", &m_volumeShader))
605 if (!prepareShaderProgram(
":/ShaderFiles/videoDiff.vert",
":/ShaderFiles/videoDiff.frag", &m_videoDiffShader))
613 if (event->buttons() & Qt::RightButton ||
event->buttons() & Qt::MidButton)
615 m_oldMousePos = mapFromGlobal(QCursor::pos());
616 setCursor(Qt::BlankCursor);
626 setCursor(Qt::ArrowCursor);
632 m_cameraDistance += (float)event->delta() / (float) 100;
642 if(event->buttons() & Qt::RightButton ||
event->buttons() & Qt::MidButton)
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();
648 if (event->buttons() & Qt::RightButton)
650 m_cameraAngleSide -= dx * 180;
651 m_cameraAngleUp -= dy * 180;
653 if (m_cameraAngleSide < 0)
654 m_cameraAngleSide = 360 + m_cameraAngleSide;
656 if (m_cameraAngleSide > 360)
657 m_cameraAngleSide = m_cameraAngleSide - 360;
659 if (m_cameraAngleUp < -90)
660 m_cameraAngleUp = -90;
662 if (m_cameraAngleUp > 90)
663 m_cameraAngleUp = 90;
666 if (event->buttons() & Qt::MidButton)
668 QMatrix4x4 cameraTransformation;
670 QVector3D cameraMotion;
671 cameraMotion.setX(- dx * 50);
672 cameraMotion.setY(dy * 50);
674 cameraTransformation.rotate(m_cameraAngleSide, 0, 1, 0);
675 cameraTransformation.rotate(m_cameraAngleUp, 1, 0, 0);
677 cameraMotion = cameraTransformation * cameraMotion;
679 QMatrix4x4 cameraPositioning;
681 cameraPositioning.translate(cameraMotion);
683 m_cameraCenter = cameraPositioning * m_cameraCenter;
689 QCursor::setPos(mapToGlobal(m_oldMousePos));
698 m_stepSize = stepSize;
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);
727 if (p_videoDiffBuffer == NULL)
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);
735 calculateVideoDiffBuffer(
false);
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);
749 if (p_videoNDiffBuffer == NULL)
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);
757 calculateVideoDiffBuffer(
true);
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);
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);