19 #include <vtkOpenGLRenderWindow.h> 21 #include <vtkTextureObject.h> 22 #include <vtkOpenGLBufferObject.h> 23 #include <vtkImageData.h> 24 #include <vtkSetGet.h> 25 #include <vtkFloatArray.h> 26 #include <vtkPixelBufferObject.h> 27 #include <vtkUnsignedCharArray.h> 28 #include <vtkTextureUnitManager.h> 43 if(!opengl_renderwindow)
53 CX_LOG_DEBUG() <<
"IsDrawable: " << opengl_renderwindow->IsDrawable();
54 CX_LOG_DEBUG() <<
"Context support for open gl core 3.2: " << (vtkOpenGLRenderWindow::GetContextSupportsOpenGL32() ?
"true" :
"false");
55 CX_LOG_DEBUG() <<
"Context was created at: " << opengl_renderwindow->GetContextCreationTime();
56 const char *renderlib = vtkRenderWindow::GetRenderLibrary();
57 CX_LOG_DEBUG() <<
"GetRenderLibrary: " << ((renderlib!=0) ? std::string(renderlib) :
"NOT FOUND");
67 mContext(sharedContext)
77 return m3DTextureObjects.count(image_uid);
86 retval = m3DTextureObjects.at(image_uid).first;
100 std::map<QString, std::pair<vtkTextureObjectPtr, unsigned long> >::iterator it = m3DTextureObjects.find(image_uid);
102 if(it != m3DTextureObjects.end())
104 m3DTextureObjects.erase(it);
105 texture->ReleaseGraphicsResources(mContext);
120 pixelBuffer = texture->Download();
121 int dataType = texture->GetVTKDataType();
122 unsigned width = texture->GetWidth();
123 unsigned height = texture->GetHeight();
124 unsigned depth = texture->GetDepth();
125 unsigned dims[3] = {width, height, depth};
126 int numComps = texture->GetComponents();
127 vtkIdType increments[3] = {0, 0, 0};
128 imageData->SetExtent(0, width-1, 0, height-1, 0, depth-1);
130 imageData->AllocateScalars(dataType, numComps);
131 void* data = imageData->GetScalarPointer();
132 pixelBuffer->Download3D(dataType, data, dims, numComps, increments);
136 CX_LOG_ERROR() <<
"SharedOpenGLContext::downloadImageFromTextureBuffer failed";
144 mContext->MakeCurrent();
145 return mContext->IsCurrent();
150 int texture_units_in_use = 0;
151 texture_units_in_use += m3DTextureObjects.size();
152 texture_units_in_use += m1DTextureObjects.size();
153 return texture_units_in_use;
159 bool success =
false;
163 CX_LOG_ERROR() <<
"Cannot upload en empty image as a 3D texture";
167 unsigned long new_modified_time = image->getBaseVtkImageData()->GetMTime();
168 std::map<QString, std::pair<vtkTextureObjectPtr, unsigned long> >::iterator it = m3DTextureObjects.find(image->getUid());
169 bool uploaded_but_modified = (it != m3DTextureObjects.end() && (it->second.second != new_modified_time) );
170 bool not_uploaded = it == m3DTextureObjects.end();
171 bool uploade_and_not_modified = (it != m3DTextureObjects.end() && (it->second.second == new_modified_time) );
173 if( uploaded_but_modified || not_uploaded)
177 int* dims = vtkImageData->GetDimensions();
178 int dataType = vtkImageData->GetScalarType();
179 int numComps = vtkImageData->GetNumberOfScalarComponents();
180 int coordinate[3] = {dims[0]/2, dims[1]/2, dims[2]/2};
181 void* data = vtkImageData->GetScalarPointer();
195 texture_object = vtkTextureObjectPtr::New();
199 success = this->create3DTextureObject(texture_object, dims[0], dims[1], dims[2], dataType, numComps, data, mContext);
200 m3DTextureObjects[image->getUid()] = std::make_pair(texture_object, vtkImageData->GetMTime());
202 else if(uploade_and_not_modified)
249 bool success =
false;
251 if(lutTable->GetSize() == 0)
253 CX_LOG_ERROR() <<
"Cannot upload en empty LUT table as a 1D texture";
257 unsigned long new_modified_time = lutTable->GetMTime();
258 std::map<QString, std::pair<vtkTextureObjectPtr, unsigned long> >::iterator it = m1DTextureObjects.find(imageUid);
259 bool uploaded_but_modified = (it != m1DTextureObjects.end() && (it->second.second != new_modified_time) );
260 bool not_uploaded = it == m1DTextureObjects.end();
261 bool uploade_and_not_modified = (it != m1DTextureObjects.end() && (it->second.second == new_modified_time) );
263 if( uploaded_but_modified || not_uploaded)
266 int lutSize = lutTable->GetNumberOfTuples();
267 int lutDataSize = lutSize * lutTable->GetNumberOfComponents();
271 std::vector<float> normalizeLUT;
272 normalizeLUT.resize(lutDataSize);
273 unsigned char* ptr = lutTable->GetPointer(0);
275 for (
int i = 0; i < normalizeLUT.size(); ++i)
277 normalizeLUT[i] = ((float) *ptr) / 255.0;
281 unsigned int width = lutSize;
282 int dataType = VTK_FLOAT;
283 int numComps = lutTable->GetNumberOfComponents();
284 void *data = &(*normalizeLUT.begin());
288 if(!texture_object.GetPointer())
291 texture_object = vtkTextureObjectPtr::New();
295 success = this->create1DTextureObject(texture_object, width, dataType, numComps, data, mContext);
297 m1DTextureObjects[imageUid] = std::make_pair(texture_object, lutTable->GetMTime());
299 else if(uploade_and_not_modified)
313 return m1DTextureObjects.count(image_uid);
321 retval = m1DTextureObjects.at(image_uid).first;
328 bool success =
false;
330 std::map<QString, std::pair<vtkTextureObjectPtr, unsigned long> >::iterator it = m1DTextureObjects.find(image_uid);
332 if(it != m1DTextureObjects.end())
334 m1DTextureObjects.erase(it);
335 texture->ReleaseGraphicsResources(mContext);
345 bool success =
false;
352 if(!texture_coordinates)
357 if(texture_coordinates->GetNumberOfTuples() < 1)
359 CX_LOG_ERROR() <<
"Cannot upload en empty array as 3D texture coordinates";
363 int numberOfLines = texture_coordinates->GetNumberOfTuples();
364 int numberOfComponentsLine = texture_coordinates->GetNumberOfComponents();
365 vtkOpenGLBufferObjectPtr buffer = allocateAndUploadArrayBuffer(uid, numberOfLines, numberOfComponentsLine, texture_coordinates->GetPointer(0));
369 mTextureCoordinateBuffers[uid] = buffer;
378 return mTextureCoordinateBuffers.count(uid);
387 retval = mTextureCoordinateBuffers.at(uid);
397 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 402 CX_LOG_ERROR() <<
"Could not make current for 3D texture";
406 texture_object->SetContext(opengl_renderwindow);
409 if(texture_object->Create3DFromRaw(width, height, depth, numComps, dataType, data))
416 texture_object->Activate();
418 texture_object->SetWrapS(vtkTextureObject::ClampToBorder);
419 texture_object->SetWrapT(vtkTextureObject::ClampToBorder);
420 texture_object->SetWrapR(vtkTextureObject::ClampToBorder);
421 if(this->useLinearInterpolation())
423 texture_object->SetMagnificationFilter(vtkTextureObject::Linear);
424 texture_object->SetMinificationFilter(vtkTextureObject::Linear);
428 texture_object->SetMagnificationFilter(vtkTextureObject::Nearest);
429 texture_object->SetMinificationFilter(vtkTextureObject::Nearest);
431 texture_object->SendParameters();
432 texture_object->Deactivate();
443 bool SharedOpenGLContext::useLinearInterpolation()
const 445 return settings()->
value(
"View2D/useLinearInterpolationIn2DRendering").toBool();
452 CX_LOG_ERROR() <<
"Could not make current for 1D texture";
456 texture_object->SetContext(opengl_renderwindow);
458 if(texture_object->Create1DFromRaw(width, numComps, dataType, data))
464 texture_object->Activate();
466 texture_object->SetWrapS(vtkTextureObject::ClampToEdge);
467 texture_object->SetMagnificationFilter(vtkTextureObject::Linear);
468 texture_object->SetMinificationFilter(vtkTextureObject::Linear);
469 texture_object->SendParameters();
473 texture_object->Deactivate();
484 vtkOpenGLBufferObjectPtr SharedOpenGLContext::allocateAndUploadArrayBuffer(QString uid,
int numberOfLines,
int numberOfComponentsLine,
const float *data)
const 496 CX_LOG_ERROR() <<
"Could not make current for ArraryBuffer";
497 return buffer_object;
507 buffer_object = vtkOpenGLBufferObjectPtr::New();
510 buffer_object->GenerateBuffer(vtkOpenGLBufferObject::ArrayBuffer);
512 if(buffer_object->Bind())
515 if(!buffer_object->Upload(
517 numberOfLines*numberOfComponentsLine,
518 vtkOpenGLBufferObject::ArrayBuffer
521 CX_LOG_ERROR() <<
"Error uploading buffer object data.";
532 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.