Mercurial > hg > orthanc-stone
comparison Framework/Scene2D/Internals/OpenGLLookupTableTextureRenderer.cpp @ 860:238693c3bc51 am-dev
merge default -> am-dev
author | Alain Mazy <alain@mazy.be> |
---|---|
date | Mon, 24 Jun 2019 14:35:00 +0200 |
parents | 266e2b0b9abc |
children | 6e888cf6a48b |
comparison
equal
deleted
inserted
replaced
856:a6e17a5a39e7 | 860:238693c3bc51 |
---|---|
1 /** | |
2 * Stone of Orthanc | |
3 * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics | |
4 * Department, University Hospital of Liege, Belgium | |
5 * Copyright (C) 2017-2019 Osimis S.A., Belgium | |
6 * | |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU Affero General Public License | |
9 * as published by the Free Software Foundation, either version 3 of | |
10 * the License, or (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Affero General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Affero General Public License | |
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 **/ | |
20 | |
21 | |
22 #include "OpenGLLookupTableTextureRenderer.h" | |
23 | |
24 namespace OrthancStone | |
25 { | |
26 namespace Internals | |
27 { | |
28 void OpenGLLookupTableTextureRenderer::LoadTexture( | |
29 const LookupTableTextureSceneLayer& layer) | |
30 { | |
31 const Orthanc::ImageAccessor& source = layer.GetTexture(); | |
32 const unsigned int width = source.GetWidth(); | |
33 const unsigned int height = source.GetHeight(); | |
34 | |
35 if ((texture_.get() == NULL) || | |
36 (texture_->GetWidth() != width) || | |
37 (texture_->GetHeight() != height)) | |
38 { | |
39 | |
40 texture_.reset(new Orthanc::Image( | |
41 Orthanc::PixelFormat_RGBA32, | |
42 width, | |
43 height, | |
44 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 } | |
60 | |
61 Orthanc::ImageAccessor target; | |
62 texture_->GetWriteableAccessor(target); | |
63 | |
64 const std::vector<uint8_t>& lut = layer.GetLookupTable(); | |
65 if (lut.size() != 4 * 256) | |
66 { | |
67 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError); | |
68 } | |
69 | |
70 assert(source.GetFormat() == Orthanc::PixelFormat_Float32 && | |
71 target.GetFormat() == Orthanc::PixelFormat_RGBA32 && | |
72 sizeof(float) == 4); | |
73 | |
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 } | |
103 | |
104 context_.MakeCurrent(); | |
105 glTexture_.reset(new OpenGL::OpenGLTexture); | |
106 glTexture_->Load(*texture_, layer.IsLinearInterpolation()); | |
107 layerTransform_ = layer.GetTransform(); | |
108 } | |
109 | |
110 | |
111 OpenGLLookupTableTextureRenderer::OpenGLLookupTableTextureRenderer( | |
112 OpenGL::IOpenGLContext& context, | |
113 OpenGLColorTextureProgram& program, | |
114 const LookupTableTextureSceneLayer& layer) | |
115 : context_(context) | |
116 , program_(program) | |
117 { | |
118 LoadTexture(layer); | |
119 } | |
120 | |
121 | |
122 void OpenGLLookupTableTextureRenderer::Render(const AffineTransform2D& transform) | |
123 { | |
124 if (glTexture_.get() != NULL) | |
125 { | |
126 program_.Apply( | |
127 *glTexture_, | |
128 AffineTransform2D::Combine(transform, layerTransform_), | |
129 true); | |
130 } | |
131 } | |
132 | |
133 | |
134 void OpenGLLookupTableTextureRenderer::Update(const ISceneLayer& layer) | |
135 { | |
136 // Should never happen (no revisions in color textures) | |
137 LoadTexture(dynamic_cast<const LookupTableTextureSceneLayer&>(layer)); | |
138 } | |
139 } | |
140 } |