comparison Framework/Scene2D/Internals/OpenGLLookupTableTextureRenderer.cpp @ 947:1091b2adeb5a toa2019081001

Fixed animation frame stopping when returning false + big work on the OpenGL objects to make them lost context-safe + debug code to forcefully tag a context as lost + debug macros
author Benjamin Golinvaux <bgo@osimis.io>
date Sat, 10 Aug 2019 13:07:31 +0200
parents 6e888cf6a48b
children f6be9412e42a
comparison
equal deleted inserted replaced
946:dbe3e1e47019 947:1091b2adeb5a
26 namespace Internals 26 namespace Internals
27 { 27 {
28 void OpenGLLookupTableTextureRenderer::LoadTexture( 28 void OpenGLLookupTableTextureRenderer::LoadTexture(
29 const LookupTableTextureSceneLayer& layer) 29 const LookupTableTextureSceneLayer& layer)
30 { 30 {
31 const Orthanc::ImageAccessor& source = layer.GetTexture(); 31 if (!context_.IsContextLost())
32 const unsigned int width = source.GetWidth(); 32 {
33 const unsigned int height = source.GetHeight(); 33 const Orthanc::ImageAccessor& source = layer.GetTexture();
34 const unsigned int width = source.GetWidth();
35 const unsigned int height = source.GetHeight();
34 36
35 if ((texture_.get() == NULL) || 37 if ((texture_.get() == NULL) ||
36 (texture_->GetWidth() != width) || 38 (texture_->GetWidth() != width) ||
37 (texture_->GetHeight() != height)) 39 (texture_->GetHeight() != height))
38 { 40 {
39 41
40 texture_.reset(new Orthanc::Image( 42 texture_.reset(new Orthanc::Image(
41 Orthanc::PixelFormat_RGBA32, 43 Orthanc::PixelFormat_RGBA32,
42 width, 44 width,
43 height, 45 height,
44 false)); 46 false));
45 }
46
47 {
48
49 const float a = layer.GetMinValue();
50 float slope = 0;
51
52 if (layer.GetMinValue() >= layer.GetMaxValue())
53 {
54 slope = 0;
55 }
56 else
57 {
58 slope = 256.0f / (layer.GetMaxValue() - layer.GetMinValue());
59 } 47 }
60 48
61 Orthanc::ImageAccessor target; 49 {
62 texture_->GetWriteableAccessor(target);
63 50
64 const std::vector<uint8_t>& lut = layer.GetLookupTable(); 51 const float a = layer.GetMinValue();
65 if (lut.size() != 4 * 256) 52 float slope = 0;
66 { 53
67 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); 54 if (layer.GetMinValue() >= layer.GetMaxValue())
55 {
56 slope = 0;
57 }
58 else
59 {
60 slope = 256.0f / (layer.GetMaxValue() - layer.GetMinValue());
61 }
62
63 Orthanc::ImageAccessor target;
64 texture_->GetWriteableAccessor(target);
65
66 const std::vector<uint8_t>& lut = layer.GetLookupTable();
67 if (lut.size() != 4 * 256)
68 {
69 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError);
70 }
71
72 assert(source.GetFormat() == Orthanc::PixelFormat_Float32 &&
73 target.GetFormat() == Orthanc::PixelFormat_RGBA32 &&
74 sizeof(float) == 4);
75
76 for (unsigned int y = 0; y < height; y++)
77 {
78 const float* p = reinterpret_cast<const float*>(source.GetConstRow(y));
79 uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
80
81 for (unsigned int x = 0; x < width; x++)
82 {
83 float v = (*p - a) * slope;
84 if (v <= 0)
85 {
86 v = 0;
87 }
88 else if (v >= 255)
89 {
90 v = 255;
91 }
92
93 uint8_t vv = static_cast<uint8_t>(v);
94
95 q[0] = lut[4 * vv + 0]; // R
96 q[1] = lut[4 * vv + 1]; // G
97 q[2] = lut[4 * vv + 2]; // B
98 q[3] = lut[4 * vv + 3]; // A
99
100 p++;
101 q += 4;
102 }
103 }
68 } 104 }
69 105
70 assert(source.GetFormat() == Orthanc::PixelFormat_Float32 && 106 context_.MakeCurrent();
71 target.GetFormat() == Orthanc::PixelFormat_RGBA32 && 107 glTexture_.reset(new OpenGL::OpenGLTexture(context_));
72 sizeof(float) == 4); 108 glTexture_->Load(*texture_, layer.IsLinearInterpolation());
73 109 layerTransform_ = layer.GetTransform();
74 for (unsigned int y = 0; y < height; y++)
75 {
76 const float* p = reinterpret_cast<const float*>(source.GetConstRow(y));
77 uint8_t* q = reinterpret_cast<uint8_t*>(target.GetRow(y));
78
79 for (unsigned int x = 0; x < width; x++)
80 {
81 float v = (*p - a) * slope;
82 if (v <= 0)
83 {
84 v = 0;
85 }
86 else if (v >= 255)
87 {
88 v = 255;
89 }
90
91 uint8_t vv = static_cast<uint8_t>(v);
92
93 q[0] = lut[4 * vv + 0]; // R
94 q[1] = lut[4 * vv + 1]; // G
95 q[2] = lut[4 * vv + 2]; // B
96 q[3] = lut[4 * vv + 3]; // A
97
98 p++;
99 q += 4;
100 }
101 }
102 } 110 }
103
104 context_.MakeCurrent();
105 glTexture_.reset(new OpenGL::OpenGLTexture);
106 glTexture_->Load(*texture_, layer.IsLinearInterpolation());
107 layerTransform_ = layer.GetTransform();
108 } 111 }
109 112
110
111 OpenGLLookupTableTextureRenderer::OpenGLLookupTableTextureRenderer( 113 OpenGLLookupTableTextureRenderer::OpenGLLookupTableTextureRenderer(
112 OpenGL::IOpenGLContext& context, 114 OpenGL::IOpenGLContext& context,
113 OpenGLColorTextureProgram& program, 115 OpenGLColorTextureProgram& program,
114 const LookupTableTextureSceneLayer& layer) 116 const LookupTableTextureSceneLayer& layer)
115 : context_(context) 117 : context_(context)
121 123
122 void OpenGLLookupTableTextureRenderer::Render(const AffineTransform2D& transform, 124 void OpenGLLookupTableTextureRenderer::Render(const AffineTransform2D& transform,
123 unsigned int canvasWidth, 125 unsigned int canvasWidth,
124 unsigned int canvasHeight) 126 unsigned int canvasHeight)
125 { 127 {
126 if (glTexture_.get() != NULL) 128 if (!context_.IsContextLost() && glTexture_.get() != NULL)
127 { 129 {
128 program_.Apply( 130 program_.Apply(
129 *glTexture_, 131 *glTexture_,
130 AffineTransform2D::Combine(transform, layerTransform_), 132 AffineTransform2D::Combine(transform, layerTransform_),
131 true); 133 true);