void DVRVolume::initializeClipObjects( DrawActionBase *action, const Matrix &volumeToWorld) { DVRClipObjectsPtr clipObjects = DVRVOLUME_PARAMETER(this, DVRClipObjects); if(clipObjects != NullFC && clipObjects->getClipMode() != DVRClipObjects::Off) { DVRVolumeTexturePtr tex = DVRVOLUME_PARAMETER(this, DVRVolumeTexture); if(tex != NullFC) { const Vec3f &res = tex->getResolution(); const Vec3f &slice = tex->getSliceThickness(); Vec3f diag(res[0] * slice[0], res[1] * slice[1], res[2] * slice[2]); Vec3f sliceDir; if(getShader()->useMTSlabs()) { Slicer::getAASlicingDirection(action,&sliceDir); } else { switch (getTextures2D()) { case 0: // 3D textures Slicer::getSlicingDirection(action, &sliceDir); break; case 1: // 2D textures Slicer::getAASlicingDirection(action, &sliceDir); break; default: // auto Window *window = action->getWindow(); if(window->hasExtension(_extTex3D)) Slicer::getSlicingDirection(action, &sliceDir); else Slicer::getAASlicingDirection(action, &sliceDir); } } Plane clipReferencePlane(sliceDir, -0.5f * diag.length()); clipObjects->initialize(volumeToWorld, clipReferencePlane); clipper.setReferencePlane(clipReferencePlane); } } }
//! set the bounding volume of the node void DVRVolume::adjustVolume(Volume &volume) { volume.setValid(); volume.setEmpty(); DVRVolumeTexturePtr tex = DVRVOLUME_PARAMETER(this, DVRVolumeTexture); if (tex != NullFC) { const Vec3f & res = tex->getResolution (); const Vec3f & slice = tex->getSliceThickness(); Vec3f minBB(-0.5f * res[0] * slice[0], -0.5f * res[1] * slice[1], -0.5f * res[2] * slice[2]); Vec3f maxBB(-minBB); volume.extendBy(minBB); volume.extendBy(maxBB); } else { // something wrong with initialization - show boundingbox either Vec3f minBB(-0.5, -0.5, -0.5); Vec3f maxBB( 0.5, 0.5, 0.5); volume.extendBy(minBB); volume.extendBy(maxBB); } }
bool DVRClipper::setNumAddPerVertexAttr( DVRVolume *volume, UInt32 additionalPerVertexAttributes) { numAddPerVertexAttr = additionalPerVertexAttributes; sliceVertexData = (GLdouble*) realloc( sliceVertexData, 6 * (6 + additionalPerVertexAttributes) * sizeof(GLdouble)); if(!sliceVertexData) return false; // get clip objects DVRClipObjectsPtr clipObjects = DVRVOLUME_PARAMETER(volume, DVRClipObjects); if(clipObjects == NullFC) return true; for(UInt32 i = 0; i < clipObjects->count(); i++) { DVRClipGeometryPtr clipObject = clipObjects->get(i); if(!clipObject->setNumAddPerVertexAttr(additionalPerVertexAttributes)) return false; } return true; }
void DVRClipper::initialize(DVRVolume *volume) { if(volume == NULL) return; // get clip objects DVRClipObjectsPtr clipObjects = DVRVOLUME_PARAMETER(volume, DVRClipObjects); if(clipObjects == NullFC) return; if(!hasTesselatorSupport) { // check for glu tesselator support hasTesselatorSupport = (atof((char*)gluGetString(GLU_VERSION)) >= 1.2); if(!hasTesselatorSupport) return; } if(myTess == NULL) { myTess = gluNewTess(); // registering callback functions for glu tesselator... gluTessCallback(myTess, GLU_TESS_COMBINE_DATA, (GLvoid (CALLBACK *)()) vertexCombineCallback); gluTessCallback(myTess, GLU_TESS_VERTEX_DATA, (GLvoid (CALLBACK *)()) vertexCallback); gluTessCallback(myTess, GLU_TESS_BEGIN_DATA, (GLvoid (CALLBACK *)()) beginCallback); gluTessCallback(myTess, GLU_TESS_END_DATA, (GLvoid (CALLBACK *)()) endCallback); gluTessCallback(myTess, GLU_TESS_ERROR, (GLvoid (CALLBACK *)()) errorCallback); } }
// react to keys void keyboard(unsigned char k, int OSG_CHECK_ARG(x), int OSG_CHECK_ARG(y)) { switch(k) { case 27: { OSG::osgExit(); exit(0); } break; case 'a': { animate = 1 - animate; } break; case '+': { newMode = (newMode + 1) % numModes; } break; case '-': { newMode = (newMode > 1) ? (newMode - 1) % numModes : numModes - 1; } break; case 't': { DVRLookupTablePtr lut = DVRVOLUME_PARAMETER(volume, DVRLookupTable); if (lut != NullFC) { beginEditCP(lut, DVRLookupTable::TouchedFieldMask); lut->setTouched(true); endEditCP(lut, DVRLookupTable::TouchedFieldMask); } } break; } }
void DVRClipper::reset(DVRVolume *volume) { if(volume == NULL || !hasTesselatorSupport) return; // get clip objects DVRClipObjectsPtr clipObjects = DVRVOLUME_PARAMETER(volume, DVRClipObjects); if(clipObjects == NullFC) return; // set tesselator properties according to clip mode if(clipObjects->getClipMode() == DVRClipObjects::Intersection) { gluTessProperty(myTess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ABS_GEQ_TWO); } else { gluTessProperty(myTess, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_POSITIVE); } // reset local data for(UInt32 i = 0; i < clipObjects->count(); i++) { // reset i-th clip object DVRClipGeometryPtr clipObject = clipObjects->get(i); clipObject->resetLocalData (); clipObject->computeSeedVertices(); } }
// setup state for shading with fragment program void DVRIsoShader::activate_FragmentProgramShading(DVRVolume *volume, DrawActionBase *action) { // Initialize the fragment program if(m_pFragProg == NullFC) { FDEBUG(("Initializing fragment program ")); m_pFragProg = FragmentProgramChunk::create(); addRefCP( m_pFragProg ); FDEBUG((" - DONE\n")); // Load the appropriate program switch(m_shadingMode) { case SM_FRAGMENT_PROGRAM_3D: // SLOG << "Loading ... isoFragProg3D.asm" << std::endl; beginEditCP(m_pFragProg); { m_pFragProg->setProgram(_fragProg3D); // m_pFragProg->read( "isoFragProg3D.asm" ); } endEditCP (m_pFragProg); break; case SM_FRAGMENT_PROGRAM_2D: // SLOG << "Loading ... isoFragProg2D.asm" << std::endl; beginEditCP(m_pFragProg); { m_pFragProg->setProgram(_fragProg2D); // m_pFragProg->read( "isoFragProg2D.asm" ); } endEditCP(m_pFragProg); break; default: FFATAL(("Texture mode for fragment programs not supported " "by DVRSimpleLUTShader")); return; // break; } } // get parameters from isosurface attachment if available Real32 isoValue; UInt32 alphaMode; bool doSpecular; DVRIsoSurfacePtr isoParam = DVRVOLUME_PARAMETER(volume, DVRIsoSurface); if(isoParam != NullFC) { isoValue = isoParam->getIsoValue (); alphaMode = isoParam->getAlphaMode (); doSpecular = isoParam->getSpecularLighting(); } else { isoValue = 1.0; alphaMode = GL_GREATER; doSpecular = false; } unsigned int maxDiffuseLights = 6; // Hard-coded in the fragment program unsigned int maxSpecularLights = 6; // Set light parameters DirLightList diffuseLights; DirLightList specularLights; Color4f ambientLight; getLightSources(diffuseLights, specularLights, ambientLight); beginEditCP(m_pFragProg, ProgramChunk::ParamValuesFieldMask); { m_pFragProg->setParameter(static_cast<short int>(0), cToV(ambientLight)); // ambient color // Diffuse lights unsigned int i; DirLightList::iterator l = diffuseLights.begin(); for(i = 0; i < maxDiffuseLights && l != diffuseLights.end(); i++) { Vec3f tmp; Slicer::rotateToLocal(action,l->dir,tmp); tmp.normalize(); // diffuse direction m_pFragProg->setParameter(1 + 2 * i, Vec4f(tmp)); // diffuse color m_pFragProg->setParameter(1 + 2 * i + 1, cToV(l->color)); ++l; } for(; i < maxDiffuseLights; i++) { // diffuse direction m_pFragProg->setParameter(1 + 2 * i, Vec4f(0, 0, 0, 0)); // diffuse color m_pFragProg->setParameter(1 + 2 * i + 1, Vec4f(0, 0, 0, 0)); } // Specular lights unsigned int firstSpecId = 1 + 2 * maxDiffuseLights; i = 0; if(doSpecular) { // get and classify the slicing direction Vec3f viewDir; Slicer::getSlicingDirection(action, &viewDir); viewDir.normalize(); DirLightList::iterator ls = specularLights.begin(); for(i = 0; i < maxSpecularLights && ls != specularLights.end(); i++) { Vec3f tmp; Slicer::rotateToLocal(action,ls->dir,tmp); tmp.normalize(); // calc halfway tmp += viewDir; tmp.normalize(); // halfway vector m_pFragProg->setParameter(firstSpecId + 2 * i, Vec4f(tmp)); // specular color m_pFragProg->setParameter(firstSpecId + 2 * i + 1, cToV(ls->color)); ++ls; } } for(; i < maxSpecularLights; i++) { // specular direction m_pFragProg->setParameter(firstSpecId + 2 * i, Vec4f(0, 0, 0, 0)); // specular color m_pFragProg->setParameter(firstSpecId + 2 * i + 1, Vec4f(0, 0, 0, 0)); } } endEditCP(m_pFragProg, ProgramChunk::ParamValuesFieldMask); glPushAttrib(GL_ENABLE_BIT); // activate fragment program chunk m_pFragProg->activate(action); // no blending and lighting glDisable(GL_BLEND ); glDisable(GL_LIGHTING); // Enable Alpha Test for isosurface glEnable (GL_ALPHA_TEST ); glAlphaFunc(alphaMode, isoValue); }
void DVRClipper::clipSlice( DVRVolume *volume, DVRSlice &unclippedSlice, const Vec3f &slicingNormal, Real32 dist2RefPlane, DVRRenderSlice &clippedSlice) { const Vec3f &texScale = unclippedSlice.getTextureScale (); const Vec3f &texTranslate = unclippedSlice.getTextureTranslate(); // get clip objects DVRClipObjectsPtr clipObjects = DVRVOLUME_PARAMETER(volume, DVRClipObjects); // nothing to clip with? if(clipObjects == NullFC) { DVRRenderSlicePrimitive *newPrimitive = new DVRRenderSlicePrimitive(); newPrimitive->type = GL_TRIANGLE_FAN; for(UInt32 i = 0; i < unclippedSlice.getVertexCount(); i++) { UInt32 idx = (6+numAddPerVertexAttr)*i; sliceVertexData[idx ] = unclippedSlice.getVertex(i).getValues()[0]; sliceVertexData[idx + 1] = unclippedSlice.getVertex(i).getValues()[1]; sliceVertexData[idx + 2] = unclippedSlice.getVertex(i).getValues()[2]; // set (standard) texture coordinates sliceVertexData[idx + 3] = texScale[0] * unclippedSlice.getVertex(i).getValues()[0] + texTranslate[0]; sliceVertexData[idx + 4] = texScale[1] * unclippedSlice.getVertex(i).getValues()[1] + texTranslate[1]; sliceVertexData[idx + 5] = texScale[2] * unclippedSlice.getVertex(i).getValues()[2] + texTranslate[2]; newPrimitive->vertices.push_back(&sliceVertexData[idx]); } clippedSlice.push_back(newPrimitive); return; } if(!hasTesselatorSupport) return; // render colored contours only (usefull for debugging) if(clipObjects->getDoContours()) { glDisable(GL_TEXTURE ); glDisable(GL_LIGHTING ); glBegin (GL_LINE_STRIP); { int col = 0; for(UInt32 i = 0; i < unclippedSlice.getVertexCount(); i++) { glColor3f(col % 3 == 0 ? 1.0f : 0.0f, col % 3 == 1 ? 1.0f : 0.0f, col % 3 == 2 ? 1.0f : 0.0f); col++; glVertex3fv(unclippedSlice.getVertex(i).getValues()); } } glEnd(); bool clipAwayOutside = clipObjects->getClipMode() == DVRClipObjects::Difference; for(UInt32 i = 0; i < clipObjects->count(); i++) { // get i-th clip object DVRClipGeometryPtr clipObject = clipObjects->get(i); // compute the contours of the triangles intersecting the // current slice const DVRTriangleList &contours = clipObject->getContours(dist2RefPlane, !clipAwayOutside, slicingNormal); if(!contours.empty()) { DVRTriangle *current; DVRTriangle *contourStart; // iterate over all contours DVRTriangleList::const_iterator contoursIt; for(contoursIt = contours.begin(); contoursIt != contours.end (); contoursIt++) { contourStart = current = *contoursIt; glBegin(GL_LINE_STRIP); { int col = 0; // iterate over all triangles in the current contour do { glColor3f(col % 3 == 0 ? 1.0f : 0.0f, col % 3 == 1 ? 1.0f : 0.0f, col % 3 == 2 ? 1.0f : 0.0f); col++; glVertex3dv(current->cutPoint); current = current->contourNeighbour; } while(current!= contourStart); } glEnd(); } } } glEnable(GL_TEXTURE ); glEnable(GL_LIGHTING); } else { // tesselate and render the clipped slices // set the slice normal for tesselation gluTessNormal(myTess, slicingNormal[0], slicingNormal[1], slicingNormal[2]); clippedSlice.clear(); gluTessBeginPolygon(myTess, &clippedSlice); // set the slice's base contour gluTessBeginContour(myTess); for(UInt32 i = 0; i < unclippedSlice.getVertexCount(); i++) { UInt32 idx = (6 + numAddPerVertexAttr) * i; sliceVertexData[idx ] = unclippedSlice.getVertex(i).getValues()[0]; sliceVertexData[idx + 1] = unclippedSlice.getVertex(i).getValues()[1]; sliceVertexData[idx + 2] = unclippedSlice.getVertex(i).getValues()[2]; // set (standard) texture coordinates sliceVertexData[idx + 3] = texScale[0] * unclippedSlice.getVertex(i).getValues()[0] + texTranslate[0]; sliceVertexData[idx + 4] = texScale[1] * unclippedSlice.getVertex(i).getValues()[1] + texTranslate[1]; sliceVertexData[idx + 5] = texScale[2] * unclippedSlice.getVertex(i).getValues()[2] + texTranslate[2]; gluTessVertex(myTess, &sliceVertexData[idx], &sliceVertexData[idx]); } gluTessEndContour(myTess); // set contours of clip objects if(clipObjects->getClipMode() != DVRClipObjects::Off) { // get clip mode bool clipAwayOutside = clipObjects->getClipMode() == DVRClipObjects::Difference; // add the contours of the intersections of the clip geometries // with the slice for(UInt32 i = 0; i < clipObjects->count(); i++) { // get i-th clip object DVRClipGeometryPtr clipObject = clipObjects->get(i); // compute the contours of the triangles intersecting // the current slice const DVRTriangleList &contours = clipObject->getContours( dist2RefPlane, !clipAwayOutside, slicingNormal); if(!contours.empty()) { DVRTriangle *current; DVRTriangle *contourStart; // iterate over all contours DVRTriangleList::const_iterator contoursIt; for(contoursIt = contours.begin(); contoursIt != contours.end (); contoursIt++) { contourStart = current = *contoursIt; // start new contour gluTessBeginContour(myTess); // iterate over all triangles in the current contour do { // set (standard) texture coordinates current->cutPoint[3] = texScale[0] * current->cutPoint[0] + texTranslate[0]; current->cutPoint[4] = texScale[1] * current->cutPoint[1] + texTranslate[1]; current->cutPoint[5] = texScale[2] * current->cutPoint[2] + texTranslate[2]; if(!current->cutPoint) std::cerr << "WTF: cutPoint is NULL" << std::endl; gluTessVertex(myTess, current->cutPoint, current->cutPoint); current = current->contourNeighbour; } while(current != contourStart); gluTessEndContour(myTess); } } } } gluTessEndPolygon(myTess); } }