• Main Page
  • Namespaces
  • Classes
  • Files
  • File List
  • File Members

volumerenderer.cpp

Go to the documentation of this file.
00001 #include <GL/glew.h>
00002 #include <QtGui>
00003 #include <QtOpenGL>
00004 
00005 /*//#define GL_GLEXT_PROTOTYPES
00006 #include <GL/gl.h>
00007 #include <GL/glu.h>
00008 #include "GL/wglext.h"
00009 */
00010 //#include "GL/glext.h"
00011 
00012 #include <math.h>
00013 #include <iostream>
00014 
00015 
00016 #include "volumerenderer.h"
00017 
00018 VolumeRenderer::VolumeRenderer(QWidget *parent)
00019     : QGLWidget(QGLFormat(QGL::SampleBuffers), parent)
00020 {
00021     transferLUT = QImage(1024, 1, QImage::Format_ARGB32);
00022 
00023     image = new QImage(100, 100, QImage::Format_RGB32);
00024 
00025         xRot = 0;
00026         yRot = 0;
00027         zRot = 0;
00028 
00029     volume = 0;
00030     options = 0;
00031 }
00032 
00033 VolumeRenderer::~VolumeRenderer()
00034 {
00035 
00036 }
00037 
00038 QRgb VolumeRenderer::transfer(float value)
00039 {
00040     value = value < 0.f ? 0.f : value;
00041     value = value > 1.f ? 1.f : value;
00042 
00043     int index = value * (transferLUT.width() - 1);
00044 
00045     return transferLUT.pixel(index, 0);
00046 }
00047 
00048 void VolumeRenderer::updateTransfer()
00049 {
00050     transferLUT.fill(0x00000000);
00051 
00052     QGradient g = QLinearGradient(QPoint(0, 0), QPoint(transferLUT.width(),0));
00053 
00054     for (int i=0; i<m_stops.size(); ++i) {
00055         g.setColorAt(m_stops.at(i).first, m_stops.at(i).second);
00056 
00057     }
00058 
00059     g.setSpread(QGradient::PadSpread);
00060 
00061     QPainter *p = new QPainter(&transferLUT);
00062 
00063     p->setBrush(g);
00064     p->setPen(Qt::NoPen);
00065 
00066     p->drawRect(transferLUT.rect());
00067 
00068     QColor color = QColor(transfer(0.5f));
00069     std::cout << "transfer(0.5) "  << color.alpha() << std::endl;
00070     delete p;
00071 }
00072 
00073 void VolumeRenderer::setGradientStops(const QGradientStops &stops)
00074 {
00075     m_stops = stops;
00076 
00077     updateTransfer();
00078 
00079     updateGL();
00080 }
00081 
00082 void VolumeRenderer::setVolume(Volume *volume)
00083 {
00084     this->volume = volume;
00085 
00086 
00087     GLfloat *data = new GLfloat[volume->GetSize()];
00088     /*for (int i = 0; i < volume->GetWidth(); ++i)
00089     {
00090         for (int j = 0; j < volume->GetHeight(); ++j)
00091         {
00092             for (int i = 0; i < volume->GetDepth(); ++k)
00093             {
00094             }
00095         }
00096     }
00097     */
00098     for (int i = 0; i < volume->GetSize(); ++i)
00099     {
00100         data[i] = volume->Get(i).GetValue();
00101     }
00102 
00103     //glActiveTexture(GL_TEXTURE0);
00104     glActiveTextureEXT1(GL_TEXTURE0);
00105     glBindTexture(GL_TEXTURE_3D, textureName);
00106 
00107     glTexImage3DEXT1(GL_TEXTURE_3D, 0, GL_ALPHA,
00108     //glTexImage3D(GL_TEXTURE_3D, 0, GL_ALPHA,
00109                  volume->GetWidth(), volume->GetHeight(), volume->GetDepth(),
00110                  0, GL_ALPHA, GL_FLOAT, data);
00111 
00112     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER,GL_LINEAR);
00113     glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER,GL_LINEAR);
00114 
00115     delete[] data;
00116 
00117     updateGL();
00118 }
00119 
00120 void VolumeRenderer::setTransfer()
00121 {
00122     glActiveTextureEXT1(GL_TEXTURE1);
00123     glBindTexture(GL_TEXTURE_1D, transferTextureName);
00124 
00125     GLuint *data = new GLuint[transferLUT.width()];
00126     for (int i=0; i<transferLUT.width(); i++) {
00127         QRgb pixel = transferLUT.pixel(i, 0);
00128         GLuint pixel_t = (pixel&0xff000000)
00129                          | ((pixel&0x00ff0000)>>16)
00130                          | (pixel&0x0000ff00)
00131                          | ((pixel&0x000000ff)<<16);
00132         data[i] = pixel_t;
00133     }
00134 
00135     glTexImage1D(GL_TEXTURE_1D, 0, 4, transferLUT.width(), 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
00136     glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
00137     glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
00138 
00139     delete[] data;
00140 }
00141 
00142 void VolumeRenderer::setRenderingOptions(RenderingOptions *options)
00143 {
00144     this->options = options;
00145 
00146     updateGL();
00147 }
00148 
00149 
00150 /****************************************************************************
00151  **
00152  ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
00153  ** All rights reserved.
00154  ** Contact: Nokia Corporation (qt-info@nokia.com)
00155  **
00156  ** This file is part of the examples of the Qt Toolkit.
00157  **
00158  ** $QT_BEGIN_LICENSE:BSD$
00159  ** You may use this file under the terms of the BSD license as follows:
00160  **
00161  ** "Redistribution and use in source and binary forms, with or without
00162  ** modification, are permitted provided that the following conditions are
00163  ** met:
00164  **   * Redistributions of source code must retain the above copyright
00165  **     notice, this list of conditions and the following disclaimer.
00166  **   * Redistributions in binary form must reproduce the above copyright
00167  **     notice, this list of conditions and the following disclaimer in
00168  **     the documentation and/or other materials provided with the
00169  **     distribution.
00170  **   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
00171  **     the names of its contributors may be used to endorse or promote
00172  **     products derived from this software without specific prior written
00173  **     permission.
00174  **
00175  ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00176  ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00177  ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
00178  ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
00179  ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00180  ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
00181  ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
00182  ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
00183  ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00184  ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
00185  ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
00186  ** $QT_END_LICENSE$
00187  **
00188  ****************************************************************************/
00189 
00190 
00191 
00192  //#include "VolumeRenderer.h"
00193  //#include "qtlogo.h"
00194 
00195  #ifndef GL_MULTISAMPLE
00196  #define GL_MULTISAMPLE  0x809D
00197  #endif
00198 
00199 
00200  QSize VolumeRenderer::minimumSizeHint() const
00201  {
00202      return QSize(200, 200);
00203  }
00204 
00205  QSize VolumeRenderer::sizeHint() const
00206  {
00207      return QSize(400, 400);
00208  }
00209 
00210  static void qNormalizeAngle(int &angle)
00211  {
00212      while (angle < 0)
00213          angle += 360 * 16;
00214      while (angle > 360 * 16)
00215          angle -= 360 * 16;
00216  }
00217 
00218  void VolumeRenderer::setXRotation(int angle)
00219  {
00220      qNormalizeAngle(angle);
00221      if (angle != xRot) {
00222          xRot = angle;
00223          emit xRotationChanged(angle);
00224          updateGL();
00225      }
00226  }
00227 
00228  void VolumeRenderer::setYRotation(int angle)
00229  {
00230      qNormalizeAngle(angle);
00231      if (angle != yRot) {
00232          yRot = angle;
00233          emit yRotationChanged(angle);
00234          updateGL();
00235      }
00236  }
00237 
00238  void VolumeRenderer::setZRotation(int angle)
00239  {
00240      qNormalizeAngle(angle);
00241      if (angle != zRot) {
00242          zRot = angle;
00243          emit zRotationChanged(angle);
00244          updateGL();
00245      }
00246  }
00247 
00248  void VolumeRenderer::initializeGL()
00249  {
00251      std::cerr << "Widget is valid: " << isValid() << std::endl;
00252      std::cerr << "context " << QGLContext::currentContext() << std::endl;
00253      std::cerr << "has OpenGL shader: " << QGLShaderProgram::hasOpenGLShaderPrograms() << std::endl;
00254      std::cerr << "context " << context() << " is valid " << context()->isValid() << std::endl;
00255      program = new QGLShaderProgram(context());
00256 
00257 
00258 
00259      //qglClearColor(qtPurple.dark());
00260      glClearColor(0.0, 0.0, 0.0, 1.0);
00261 
00262      glEnable(GL_DEPTH_TEST);
00263      glEnable(GL_CULL_FACE);
00264      glShadeModel(GL_SMOOTH);
00265      glEnable(GL_LIGHTING);
00266      glEnable(GL_LIGHT0);
00267      glEnable(GL_MULTISAMPLE);
00268      glEnable(GL_TEXTURE_1D);
00269      glEnable(GL_TEXTURE_3D);
00270      static GLfloat lightPosition[4] = { 0.5, 5.0, 7.0, 1.0 };
00271      glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
00272 
00273      program->addShaderFromSourceCode(QGLShader::Vertex,
00274          "attribute highp vec4 vertex;\n"
00275          "attribute vec4 texCoord;"
00276          "void main(void)\n"
00277          "{\n"
00278          "   gl_Position = vertex;\n"
00279          "  gl_TexCoord[0] = texCoord;"
00280          "}");
00281      std::cout << "Vertex shader log: " << program->log().toStdString().c_str() << std::endl;
00282 
00283      program->addShaderFromSourceFile(QGLShader::Fragment, "../Beispiel1/FragmentShader.glsl");
00284 
00285      std::cerr << "Fragment shader log: " << program->log().toStdString().c_str() << std::endl;
00286      program->link();
00287      std::cout << "Shader link log: " << program->log().toStdString().c_str() << std::endl;
00288      program->bind();
00289 
00290      vertexLocation = program->attributeLocation("vertex");
00291      texCoordLocation = program->attributeLocation("texCoord");
00292 
00293      n0Location = program->uniformLocation("n0");
00294      uLocation = program->uniformLocation("u");
00295      vLocation = program->uniformLocation("v");
00296      volumeSizeLocation = program->uniformLocation("volumeSize");
00297      volumeResolutionLocation = program->uniformLocation("volumeResolution");
00298      NLocation = program->uniformLocation("N");
00299      samplerLocation = program->uniformLocation("sampler");
00300      lightColorLocation = program->uniformLocation("c_light");
00301      ambientColorLocation = program->uniformLocation("c_ambient");
00302      diffuseColorLocation = program->uniformLocation("c_diffuse");
00303      specularColorLocation = program->uniformLocation("c_specular");
00304      specularExponentLocation = program->uniformLocation("c_exponent");
00305      transferLocation = program->uniformLocation("transferSampler");
00306      k1Location = program->uniformLocation("k1");
00307      k2Location = program->uniformLocation("k2");
00308 
00309      // 3D texture
00310      glGenTextures(1, &textureName);
00311      glGenTextures(1, &transferTextureName);
00312 
00313      //glTexImage3D = (PFNGLTEXIMAGE3DPROC) wglGetProcAddress("glTexImage3D");
00314     glTexImage3DEXT1 = (PFNGLTEXIMAGE3DEXTPROC)wglGetProcAddress("glTexImage3DEXT");
00315     glActiveTextureEXT1 = (PFNGLACTIVETEXTUREPROC)wglGetProcAddress("glActiveTextureEXT");
00316 
00317  }
00318 
00319  void VolumeRenderer::paintGL()
00320  {
00321      glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00322 
00323      if (! volume || ! options)
00324          return;
00325 
00326      float x = width/4, y = height/4;
00327     x = 1.f; y = 1.f;
00328 
00329      static GLfloat const quadVertices[] = {
00330          x,  y, 0.0f,
00331         -x,  y, 0.0f,
00332         -x, -y, 0.0f,
00333          x, -y, 0.0f
00334     };
00335 
00336      static GLfloat const texCoords[] = {
00337          width / 2,  height / 2,
00338         -width / 2,  height / 2,
00339         -width / 2, -height / 2,
00340          width / 2, -height / 2,
00341      };
00342 
00343      QMatrix4x4 pmvMatrix;
00344      pmvMatrix.rotate(xRot, QVector3D(1.f, 0, 0));
00345      pmvMatrix.rotate(yRot, QVector3D(0, 1.f, 0));
00346      pmvMatrix.rotate(zRot, QVector3D(0, 0, 1.f));
00347 
00348      QVector3D n0 = pmvMatrix * QVector3D(0, 0, -1.f);
00349      // FIXME: keep aspect ratio
00350      QVector3D u = pmvMatrix * QVector3D(1.f / width, 0, 0) * 2;
00351      QVector3D v = pmvMatrix * QVector3D(0, 1.f / height, 0) * 2;
00352 
00353      QVector3D volumeResolution(volume->GetWidth(), volume->GetHeight(), volume->GetDepth());
00354 
00355      QVector3D volumeSize(volumeResolution);
00356      float max = volumeSize.x();
00357      if (volumeSize.y() > max)
00358          max = volumeSize.y();
00359      if (volumeSize.z() > max)
00360          max = volumeSize.z();
00361      volumeSize *= 1 / max;
00362 
00363      program->enableAttributeArray(vertexLocation);
00364      program->setAttributeArray(vertexLocation, quadVertices, 3);
00365      program->enableAttributeArray(texCoordLocation);
00366      program->setAttributeArray(texCoordLocation, texCoords, 2);
00367 
00368      program->setUniformValue(n0Location, n0);
00369      program->setUniformValue(uLocation, u);
00370      program->setUniformValue(vLocation, v);
00371      program->setUniformValue(NLocation, options->N);
00372      program->setUniformValue(volumeSizeLocation, volumeSize);
00373      program->setUniformValue(volumeResolutionLocation, volumeResolution);
00374      program->setUniformValue(samplerLocation, 0);
00375      program->setUniformValue(lightColorLocation, options->light);
00376      program->setUniformValue(ambientColorLocation, options->ambient);
00377      program->setUniformValue(diffuseColorLocation, options->diffuse);
00378      program->setUniformValue(specularColorLocation, options->specular);
00379      program->setUniformValue(specularExponentLocation, options->exponent);
00380      program->setUniformValue(transferLocation, 1);
00381      program->setUniformValue(k1Location, options->k1);
00382      program->setUniformValue(k2Location, options->k2);
00383 
00384      glActiveTextureEXT1(GL_TEXTURE0);
00385      glBindTexture(GL_TEXTURE_3D, textureName);
00386      glActiveTextureEXT1(GL_TEXTURE1);
00387      glBindTexture(GL_TEXTURE_1D, transferTextureName);
00388 
00389      glDrawArrays(GL_QUADS, 0, 4);
00390 
00391      program->disableAttributeArray(vertexLocation);
00392      program->disableAttributeArray(texCoordLocation);
00393  }
00394 
00395  void VolumeRenderer::resizeGL(int width, int height)
00396  {
00397     // int side = qMin(width, height);
00398     // glViewport((width - side) / 2, (height - side) / 2, side, side);
00399 
00400     glViewport(0, 0, width, height);
00401 
00402     this->width = width;
00403     this->height = height;
00404 
00405     /*
00406      glMatrixMode(GL_PROJECTION);
00407      glLoadIdentity();
00408      glOrtho(-500.5, +500.5, -500.5, +500.5, -10.0, 150.0);
00409 
00410      glMatrixMode(GL_MODELVIEW);
00411     */
00412  }
00413 
00414  void VolumeRenderer::mousePressEvent(QMouseEvent *event)
00415  {
00416      lastPos = event->pos();
00417  }
00418 
00419  void VolumeRenderer::mouseMoveEvent(QMouseEvent *event)
00420  {
00421      int dx = event->x() - lastPos.x();
00422      int dy = event->y() - lastPos.y();
00423 
00424      static const float s = 1.f;
00425      if (event->buttons() & Qt::LeftButton) {
00426          setXRotation(xRot + s * dy);
00427          setYRotation(yRot + s * dx);
00428      } else if (event->buttons() & Qt::RightButton) {
00429          setXRotation(xRot + s * dy);
00430          setZRotation(zRot + s * dx);
00431      }
00432      lastPos = event->pos();
00433  }

Generated on Mon Dec 6 2010 12:10:16 for LU Visualisierung WS2010 - Beispiel 1 by  doxygen 1.7.2