40 #include <vtkOpenGLRenderWindow.h> 42 #include <vtkTextureObject.h> 43 #include <vtkOpenGLBufferObject.h> 44 #include <vtkImageData.h> 45 #include <vtkSetGet.h> 46 #include <vtkFloatArray.h> 47 #include <vtkPixelBufferObject.h> 48 #include <vtkUnsignedCharArray.h> 49 #include <vtkTextureUnitManager.h> 64 if(!opengl_renderwindow)
74 CX_LOG_DEBUG() <<
"IsDrawable: " << opengl_renderwindow->IsDrawable();
75 CX_LOG_DEBUG() <<
"Context support for open gl core 3.2: " << (vtkOpenGLRenderWindow::GetContextSupportsOpenGL32() ?
"true" :
"false");
76 CX_LOG_DEBUG() <<
"Context was created at: " << opengl_renderwindow->GetContextCreationTime();
77 const char *renderlib = vtkRenderWindow::GetRenderLibrary();
78 CX_LOG_DEBUG() <<
"GetRenderLibrary: " << ((renderlib!=0) ? std::string(renderlib) :
"NOT FOUND");
88 mContext(sharedContext)
98 return m3DTextureObjects.count(image_uid);
107 retval = m3DTextureObjects.at(image_uid).first;
119 bool success =
false;
121 std::map<QString, std::pair<vtkTextureObjectPtr, unsigned long> >::iterator it = m3DTextureObjects.find(image_uid);
123 if(it != m3DTextureObjects.end())
125 m3DTextureObjects.erase(it);
126 texture->ReleaseGraphicsResources(mContext);
141 pixelBuffer = texture->Download();
142 int dataType = texture->GetVTKDataType();
143 unsigned width = texture->GetWidth();
144 unsigned height = texture->GetHeight();
145 unsigned depth = texture->GetDepth();
146 unsigned dims[3] = {width, height, depth};
147 int numComps = texture->GetComponents();
148 vtkIdType increments[3] = {0, 0, 0};
149 imageData->SetExtent(0, width-1, 0, height-1, 0, depth-1);
151 imageData->AllocateScalars(dataType, numComps);
152 void* data = imageData->GetScalarPointer();
153 pixelBuffer->Download3D(dataType, data, dims, numComps, increments);
157 CX_LOG_ERROR() <<
"SharedOpenGLContext::downloadImageFromTextureBuffer failed";
165 mContext->MakeCurrent();
166 return mContext->IsCurrent();
171 int texture_units_in_use = 0;
172 texture_units_in_use += m3DTextureObjects.size();
173 texture_units_in_use += m1DTextureObjects.size();
174 return texture_units_in_use;
180 bool success =
false;
184 CX_LOG_ERROR() <<
"Cannot upload en empty image as a 3D texture";
188 unsigned long new_modified_time = image->getBaseVtkImageData()->GetMTime();
189 std::map<QString, std::pair<vtkTextureObjectPtr, unsigned long> >::iterator it = m3DTextureObjects.find(image->getUid());
190 bool uploaded_but_modified = (it != m3DTextureObjects.end() && (it->second.second != new_modified_time) );
191 bool not_uploaded = it == m3DTextureObjects.end();
192 bool uploade_and_not_modified = (it != m3DTextureObjects.end() && (it->second.second == new_modified_time) );
194 if( uploaded_but_modified || not_uploaded)
198 int* dims = vtkImageData->GetDimensions();
199 int dataType = vtkImageData->GetScalarType();
200 int numComps = vtkImageData->GetNumberOfScalarComponents();
201 int coordinate[3] = {dims[0]/2, dims[1]/2, dims[2]/2};
202 void* data = vtkImageData->GetScalarPointer();
216 texture_object = vtkTextureObjectPtr::New();
220 success = this->create3DTextureObject(texture_object, dims[0], dims[1], dims[2], dataType, numComps, data, mContext);
221 m3DTextureObjects[image->getUid()] = std::make_pair(texture_object, vtkImageData->GetMTime());
223 else if(uploade_and_not_modified)
270 bool success =
false;
272 if(lutTable->GetSize() == 0)
274 CX_LOG_ERROR() <<
"Cannot upload en empty LUT table as a 1D texture";
278 unsigned long new_modified_time = lutTable->GetMTime();
279 std::map<QString, std::pair<vtkTextureObjectPtr, unsigned long> >::iterator it = m1DTextureObjects.find(imageUid);
280 bool uploaded_but_modified = (it != m1DTextureObjects.end() && (it->second.second != new_modified_time) );
281 bool not_uploaded = it == m1DTextureObjects.end();
282 bool uploade_and_not_modified = (it != m1DTextureObjects.end() && (it->second.second == new_modified_time) );
284 if( uploaded_but_modified || not_uploaded)
287 int lutSize = lutTable->GetNumberOfTuples();
288 int lutDataSize = lutSize * lutTable->GetNumberOfComponents();
292 std::vector<float> normalizeLUT;
293 normalizeLUT.resize(lutDataSize);
294 unsigned char* ptr = lutTable->GetPointer(0);
296 for (
int i = 0; i < normalizeLUT.size(); ++i)
298 normalizeLUT[i] = ((float) *ptr) / 255.0;
302 unsigned int width = lutSize;
303 int dataType = VTK_FLOAT;
304 int numComps = lutTable->GetNumberOfComponents();
305 void *data = &(*normalizeLUT.begin());
309 if(!texture_object.GetPointer())
312 texture_object = vtkTextureObjectPtr::New();
316 success = this->create1DTextureObject(texture_object, width, dataType, numComps, data, mContext);
318 m1DTextureObjects[imageUid] = std::make_pair(texture_object, lutTable->GetMTime());
320 else if(uploade_and_not_modified)
334 return m1DTextureObjects.count(image_uid);
342 retval = m1DTextureObjects.at(image_uid).first;
349 bool success =
false;
351 std::map<QString, std::pair<vtkTextureObjectPtr, unsigned long> >::iterator it = m1DTextureObjects.find(image_uid);
353 if(it != m1DTextureObjects.end())
355 m1DTextureObjects.erase(it);
356 texture->ReleaseGraphicsResources(mContext);
366 bool success =
false;
373 if(!texture_coordinates)
378 if(texture_coordinates->GetNumberOfTuples() < 1)
380 CX_LOG_ERROR() <<
"Cannot upload en empty array as 3D texture coordinates";
384 int numberOfLines = texture_coordinates->GetNumberOfTuples();
385 int numberOfComponentsLine = texture_coordinates->GetNumberOfComponents();
386 vtkOpenGLBufferObjectPtr buffer = allocateAndUploadArrayBuffer(uid, numberOfLines, numberOfComponentsLine, texture_coordinates->GetPointer(0));
390 mTextureCoordinateBuffers[uid] = buffer;
399 return mTextureCoordinateBuffers.count(uid);
408 retval = mTextureCoordinateBuffers.at(uid);
418 bool SharedOpenGLContext::create3DTextureObject(
vtkTextureObjectPtr texture_object,
unsigned int width,
unsigned int height,
unsigned int depth,
int dataType,
int numComps,
void *data,
vtkOpenGLRenderWindowPtr opengl_renderwindow)
const 423 CX_LOG_ERROR() <<
"Could not make current for 3D texture";
427 texture_object->SetContext(opengl_renderwindow);
430 if(texture_object->Create3DFromRaw(width, height, depth, numComps, dataType, data))
437 texture_object->Activate();
439 texture_object->SetWrapS(vtkTextureObject::ClampToBorder);
440 texture_object->SetWrapT(vtkTextureObject::ClampToBorder);
441 texture_object->SetWrapR(vtkTextureObject::ClampToBorder);
442 if(this->useLinearInterpolation())
444 texture_object->SetMagnificationFilter(vtkTextureObject::Linear);
445 texture_object->SetMinificationFilter(vtkTextureObject::Linear);
449 texture_object->SetMagnificationFilter(vtkTextureObject::Nearest);
450 texture_object->SetMinificationFilter(vtkTextureObject::Nearest);
452 texture_object->SendParameters();
453 texture_object->Deactivate();
464 bool SharedOpenGLContext::useLinearInterpolation()
const 466 return settings()->
value(
"View2D/useLinearInterpolationIn2DRendering").toBool();
473 CX_LOG_ERROR() <<
"Could not make current for 1D texture";
477 texture_object->SetContext(opengl_renderwindow);
479 if(texture_object->Create1DFromRaw(width, numComps, dataType, data))
485 texture_object->Activate();
487 texture_object->SetWrapS(vtkTextureObject::ClampToEdge);
488 texture_object->SetMagnificationFilter(vtkTextureObject::Linear);
489 texture_object->SetMinificationFilter(vtkTextureObject::Linear);
490 texture_object->SendParameters();
494 texture_object->Deactivate();
505 vtkOpenGLBufferObjectPtr SharedOpenGLContext::allocateAndUploadArrayBuffer(QString uid,
int numberOfLines,
int numberOfComponentsLine,
const float *data)
const 517 CX_LOG_ERROR() <<
"Could not make current for ArraryBuffer";
518 return buffer_object;
528 buffer_object = vtkOpenGLBufferObjectPtr::New();
531 buffer_object->GenerateBuffer(vtkOpenGLBufferObject::ArrayBuffer);
533 if(buffer_object->Bind())
536 if(!buffer_object->Upload(
538 numberOfLines*numberOfComponentsLine,
539 vtkOpenGLBufferObject::ArrayBuffer
542 CX_LOG_ERROR() <<
"Error uploading buffer object data.";
553 return buffer_object;
vtkSmartPointer< class vtkTextureObject > vtkTextureObjectPtr
bool hasUploadedLUT(QString image_uid) const
bool hasUploadedImage(QString image_uid) const
bool uploadImage(ImagePtr image)
boost::shared_ptr< class Image > ImagePtr
vtkSmartPointer< class vtkFloatArray > vtkFloatArrayPtr
QVariant value(const QString &key, const QVariant &defaultValue=QVariant()) const
bool upload3DTextureCoordinates(QString uid, vtkFloatArrayPtr texture_coordinates)
vtkSmartPointer< class vtkUnsignedCharArray > vtkUnsignedCharArrayPtr
vtkImageDataPtr downloadImageFromTextureBuffer(QString image_uid)
vtkTextureObjectPtr get3DTextureForImage(QString image_uid) const
vtkOpenGLBufferObjectPtr getTextureCoordinates(QString uid) const
vtkSmartPointer< class vtkOpenGLBufferObject > vtkOpenGLBufferObjectPtr
bool delete3DTextureForImage(QString image_uid)
vtkSmartPointer< class vtkOpenGLRenderWindow > vtkOpenGLRenderWindowPtr
bool uploadLUT(QString imageUid, vtkUnsignedCharArrayPtr lutTable)
vtkSmartPointer< class vtkPixelBufferObject > vtkPixelBufferObjectPtr
Settings * settings()
Shortcut for accessing the settings instance.
bool delete1DTextureForLUT(QString image_uid)
int getNumberOfTexturesInUse() const
bool hasUploadedTextureCoordinates(QString uid) const
static bool isValid(vtkOpenGLRenderWindowPtr opengl_renderwindow, bool print=false)
void print(QString header, QRect r)
vtkTextureObjectPtr get1DTextureForLUT(QString image_uid) const
#define report_gl_error()
Namespace for all CustusX production code.