Mercurial > hg > orthanc-stone
changeset 591:b66ced2c43d4
OpenGLTextureProgram
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 26 Apr 2019 12:05:38 +0200 |
parents | 5430bcffba57 |
children | bbe29efd3d1c |
files | Framework/OpenGL/TextOpenGLProgram.cpp Framework/OpenGL/TextOpenGLProgram.h Framework/Scene2D/Internals/ColorTextureOpenGLProgram.cpp Framework/Scene2D/Internals/ColorTextureOpenGLProgram.h Framework/Scene2D/Internals/OpenGLColorTextureProgram.cpp Framework/Scene2D/Internals/OpenGLColorTextureProgram.h Framework/Scene2D/Internals/OpenGLFloatTextureProgram.cpp Framework/Scene2D/Internals/OpenGLFloatTextureProgram.h Framework/Scene2D/Internals/OpenGLTextureProgram.cpp Framework/Scene2D/Internals/OpenGLTextureProgram.h Resources/CMake/OrthancStoneConfiguration.cmake |
diffstat | 11 files changed, 527 insertions(+), 507 deletions(-) [+] |
line wrap: on
line diff
--- a/Framework/OpenGL/TextOpenGLProgram.cpp Fri Apr 26 11:33:57 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,185 +0,0 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2019 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - **/ - - -#include "TextOpenGLProgram.h" - -#include "../Fonts/OpenGLTextCoordinates.h" - -#include <Core/OrthancException.h> - - -namespace OrthancStone -{ - namespace OpenGL - { - TextOpenGLProgram::TextOpenGLProgram(IOpenGLContext& context) : - context_(context) - { - static const char* VERTEX_SHADER = - "attribute vec2 a_texcoord; \n" - "attribute vec4 a_position; \n" - "uniform mat4 u_matrix; \n" - "varying vec2 v_texcoord; \n" - "void main() \n" - "{ \n" - " gl_Position = u_matrix * a_position; \n" - " v_texcoord = a_texcoord; \n" - "}"; - - static const char* FRAGMENT_SHADER = - "uniform sampler2D u_texture; \n" - "uniform vec3 u_color; \n" - "varying vec2 v_texcoord; \n" - "void main() \n" - "{ \n" - " vec4 v = texture2D(u_texture, v_texcoord); \n" - " gl_FragColor = vec4(u_color * v.w, v.w); \n" // Premultiplied alpha - "}"; - - context_.MakeCurrent(); - - program_.reset(new OpenGLProgram); - program_->CompileShaders(VERTEX_SHADER, FRAGMENT_SHADER); - - positionLocation_ = program_->GetAttributeLocation("a_position"); - textureLocation_ = program_->GetAttributeLocation("a_texcoord"); - } - - - TextOpenGLProgram::Data::Data(IOpenGLContext& context, - const GlyphTextureAlphabet& alphabet, - const TextSceneLayer& layer) : - context_(context), - red_(layer.GetRedAsFloat()), - green_(layer.GetGreenAsFloat()), - blue_(layer.GetBlueAsFloat()), - x_(layer.GetX()), - y_(layer.GetY()), - border_(layer.GetBorder()), - anchor_(layer.GetAnchor()) - { - OpenGLTextCoordinates coordinates(alphabet, layer.GetText()); - textWidth_ = coordinates.GetTextWidth(); - textHeight_ = coordinates.GetTextHeight(); - - if (coordinates.IsEmpty()) - { - coordinatesCount_ = 0; - } - else - { - coordinatesCount_ = coordinates.GetRenderingCoords().size(); - - context_.MakeCurrent(); - glGenBuffers(2, buffers_); - - glBindBuffer(GL_ARRAY_BUFFER, buffers_[0]); - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * coordinatesCount_, - &coordinates.GetRenderingCoords() [0], GL_STATIC_DRAW); - - glBindBuffer(GL_ARRAY_BUFFER, buffers_[1]); - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * coordinatesCount_, - &coordinates.GetTextureCoords() [0], GL_STATIC_DRAW); - } - } - - - TextOpenGLProgram::Data::~Data() - { - if (!IsEmpty()) - { - context_.MakeCurrent(); - glDeleteBuffers(2, buffers_); - } - } - - - GLuint TextOpenGLProgram::Data::GetSceneLocationsBuffer() const - { - if (IsEmpty()) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); - } - else - { - return buffers_[0]; - } - } - - - GLuint TextOpenGLProgram::Data::GetTextureLocationsBuffer() const - { - if (IsEmpty()) - { - throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); - } - else - { - return buffers_[1]; - } - } - - - void TextOpenGLProgram::Apply(OpenGLTexture& fontTexture, - const Data& data, - const AffineTransform2D& transform) - { - if (!data.IsEmpty()) - { - context_.MakeCurrent(); - program_->Use(); - - double dx, dy; // In pixels - ComputeAnchorTranslation(dx, dy, data.GetAnchor(), data.GetTextWidth(), data.GetTextHeight(), data.GetBorder()); - - double x = data.GetX(); - double y = data.GetY(); - transform.Apply(x, y); - - const AffineTransform2D t = AffineTransform2D::CreateOffset(x + dx, y + dy); - - float m[16]; - t.ConvertToOpenGLMatrix(m, context_.GetCanvasWidth(), context_.GetCanvasHeight()); - - fontTexture.Bind(program_->GetUniformLocation("u_texture")); - glUniformMatrix4fv(program_->GetUniformLocation("u_matrix"), 1, GL_FALSE, m); - glUniform3f(program_->GetUniformLocation("u_color"), - data.GetRed(), data.GetGreen(), data.GetBlue()); - - glBindBuffer(GL_ARRAY_BUFFER, data.GetSceneLocationsBuffer()); - glEnableVertexAttribArray(positionLocation_); - glVertexAttribPointer(positionLocation_, COMPONENTS, GL_FLOAT, GL_FALSE, 0, 0); - - glBindBuffer(GL_ARRAY_BUFFER, data.GetTextureLocationsBuffer()); - glEnableVertexAttribArray(textureLocation_); - glVertexAttribPointer(textureLocation_, COMPONENTS, GL_FLOAT, GL_FALSE, 0, 0); - - glEnable(GL_BLEND); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDrawArrays(GL_TRIANGLES, 0, data.GetCoordinatesCount() / COMPONENTS); - glDisable(GL_BLEND); - - glDisableVertexAttribArray(positionLocation_); - glDisableVertexAttribArray(textureLocation_); - } - } - } -}
--- a/Framework/OpenGL/TextOpenGLProgram.h Fri Apr 26 11:33:57 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,138 +0,0 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2019 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - **/ - - -#pragma once - -#include "IOpenGLContext.h" -#include "OpenGLProgram.h" -#include "OpenGLTexture.h" - -#include "../Fonts/GlyphTextureAlphabet.h" -#include "../Scene2D/TextSceneLayer.h" -#include "../Toolbox/AffineTransform2D.h" - -namespace OrthancStone -{ - namespace OpenGL - { - class TextOpenGLProgram : public boost::noncopyable - { - public: - class Data : public boost::noncopyable - { - private: - IOpenGLContext& context_; - size_t coordinatesCount_; - GLuint buffers_[2]; - float red_; - float green_; - float blue_; - double x_; - double y_; - double border_; - unsigned int textWidth_; - unsigned int textHeight_; - BitmapAnchor anchor_; - - public: - Data(IOpenGLContext& context, - const GlyphTextureAlphabet& alphabet, - const TextSceneLayer& layer); - - ~Data(); - - bool IsEmpty() const - { - return coordinatesCount_ == 0; - } - - size_t GetCoordinatesCount() const - { - return coordinatesCount_; - } - - GLuint GetSceneLocationsBuffer() const; - - GLuint GetTextureLocationsBuffer() const; - - float GetRed() const - { - return red_; - } - - float GetGreen() const - { - return green_; - } - - float GetBlue() const - { - return blue_; - } - - double GetX() const - { - return x_; - } - - double GetY() const - { - return y_; - } - - double GetBorder() const - { - return border_; - } - - unsigned int GetTextWidth() const - { - return textWidth_; - } - - unsigned int GetTextHeight() const - { - return textHeight_; - } - - BitmapAnchor GetAnchor() const - { - return anchor_; - } - }; - - private: - static const unsigned int COMPONENTS = 2; - - IOpenGLContext& context_; - std::auto_ptr<OpenGLProgram> program_; - GLint positionLocation_; - GLint textureLocation_; - - public: - TextOpenGLProgram(IOpenGLContext& context); - - void Apply(OpenGLTexture& fontTexture, - const Data& data, - const AffineTransform2D& transform); - }; - } -}
--- a/Framework/Scene2D/Internals/ColorTextureOpenGLProgram.cpp Fri Apr 26 11:33:57 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,127 +0,0 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2019 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - **/ - - -#include "ColorTextureOpenGLProgram.h" - -namespace OrthancStone -{ - namespace Internals - { - ColorTextureOpenGLProgram::ColorTextureOpenGLProgram(OpenGL::IOpenGLContext& context) : - context_(context) - { - static const char* VERTEX_SHADER = - "attribute vec2 a_texcoord; \n" - "attribute vec4 a_position; \n" - "uniform mat4 u_matrix; \n" - "varying vec2 v_texcoord; \n" - "void main() \n" - "{ \n" - " gl_Position = u_matrix * a_position; \n" - " v_texcoord = a_texcoord; \n" - "}"; - - static const char* FRAGMENT_SHADER = - "uniform sampler2D u_texture; \n" - "varying vec2 v_texcoord; \n" - "void main() \n" - "{ \n" - " gl_FragColor = texture2D(u_texture, v_texcoord); \n" - "}"; - - static const float POSITIONS[COMPONENTS * COUNT] = { - 0, 0, - 0, 1, - 1, 0, - 1, 0, - 0, 1, - 1, 1 - }; - - context_.MakeCurrent(); - - program_.reset(new OpenGL::OpenGLProgram); - program_->CompileShaders(VERTEX_SHADER, FRAGMENT_SHADER); - - positionLocation_ = program_->GetAttributeLocation("a_position"); - textureLocation_ = program_->GetAttributeLocation("a_texcoord"); - - glGenBuffers(2, buffers_); - - glBindBuffer(GL_ARRAY_BUFFER, buffers_[0]); - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * COMPONENTS * COUNT, POSITIONS, GL_STATIC_DRAW); - - glBindBuffer(GL_ARRAY_BUFFER, buffers_[1]); - glBufferData(GL_ARRAY_BUFFER, sizeof(float) * COMPONENTS * COUNT, POSITIONS, GL_STATIC_DRAW); - } - - - ColorTextureOpenGLProgram::~ColorTextureOpenGLProgram() - { - context_.MakeCurrent(); - glDeleteBuffers(2, buffers_); - } - - - void ColorTextureOpenGLProgram::Apply(OpenGL::OpenGLTexture& texture, - const AffineTransform2D& transform, - bool useAlpha) - { - context_.MakeCurrent(); - program_->Use(); - - AffineTransform2D scale = AffineTransform2D::CreateScaling - (texture.GetWidth(), texture.GetHeight()); - - AffineTransform2D t = AffineTransform2D::Combine(transform, scale); - - float m[16]; - t.ConvertToOpenGLMatrix(m, context_.GetCanvasWidth(), context_.GetCanvasHeight()); - - texture.Bind(program_->GetUniformLocation("u_texture")); - glUniformMatrix4fv(program_->GetUniformLocation("u_matrix"), 1, GL_FALSE, m); - - glBindBuffer(GL_ARRAY_BUFFER, buffers_[0]); - glEnableVertexAttribArray(positionLocation_); - glVertexAttribPointer(positionLocation_, COMPONENTS, GL_FLOAT, GL_FALSE, 0, 0); - - glBindBuffer(GL_ARRAY_BUFFER, buffers_[1]); - glEnableVertexAttribArray(textureLocation_); - glVertexAttribPointer(textureLocation_, COMPONENTS, GL_FLOAT, GL_FALSE, 0, 0); - - if (useAlpha) - { - glEnable(GL_BLEND); - //glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); - glDrawArrays(GL_TRIANGLES, 0, COUNT); - glDisable(GL_BLEND); - } - else - { - glDrawArrays(GL_TRIANGLES, 0, COUNT); - } - - glDisableVertexAttribArray(positionLocation_); - glDisableVertexAttribArray(textureLocation_); - } - } -}
--- a/Framework/Scene2D/Internals/ColorTextureOpenGLProgram.h Fri Apr 26 11:33:57 2019 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,55 +0,0 @@ -/** - * Stone of Orthanc - * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics - * Department, University Hospital of Liege, Belgium - * Copyright (C) 2017-2019 Osimis S.A., Belgium - * - * This program is free software: you can redistribute it and/or - * modify it under the terms of the GNU Affero General Public License - * as published by the Free Software Foundation, either version 3 of - * the License, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, but - * WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - **/ - - -#pragma once - -#include "../../OpenGL/IOpenGLContext.h" -#include "../../OpenGL/OpenGLProgram.h" -#include "../../OpenGL/OpenGLTexture.h" -#include "../../Toolbox/AffineTransform2D.h" - -namespace OrthancStone -{ - namespace Internals - { - class ColorTextureOpenGLProgram : public boost::noncopyable - { - private: - static const unsigned int COMPONENTS = 2; - static const unsigned int COUNT = 6; // 2 triangles in 2D - - OpenGL::IOpenGLContext& context_; - std::auto_ptr<OpenGL::OpenGLProgram> program_; - GLint positionLocation_; - GLint textureLocation_; - GLuint buffers_[2]; - - public: - ColorTextureOpenGLProgram(OpenGL::IOpenGLContext& context); - - ~ColorTextureOpenGLProgram(); - - void Apply(OpenGL::OpenGLTexture& texture, - const AffineTransform2D& transform, - bool useAlpha); - }; - } -}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2D/Internals/OpenGLColorTextureProgram.cpp Fri Apr 26 12:05:38 2019 +0200 @@ -0,0 +1,63 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include "OpenGLColorTextureProgram.h" + + +static const char* FRAGMENT_SHADER = + "uniform sampler2D u_texture; \n" + "varying vec2 v_texcoord; \n" + "void main() \n" + "{ \n" + " gl_FragColor = texture2D(u_texture, v_texcoord); \n" + "}"; + + +namespace OrthancStone +{ + namespace Internals + { + OpenGLColorTextureProgram::OpenGLColorTextureProgram(OpenGL::IOpenGLContext& context) : + program_(context, FRAGMENT_SHADER) + { + } + + + void OpenGLColorTextureProgram::Apply(OpenGL::OpenGLTexture& texture, + const AffineTransform2D& transform, + bool useAlpha) + { + OpenGLTextureProgram::Execution execution(program_, texture, transform); + + if (useAlpha) + { + glEnable(GL_BLEND); + glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + execution.DrawTriangles(); + glDisable(GL_BLEND); + } + else + { + execution.DrawTriangles(); + } + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2D/Internals/OpenGLColorTextureProgram.h Fri Apr 26 12:05:38 2019 +0200 @@ -0,0 +1,43 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include "OpenGLTextureProgram.h" + +namespace OrthancStone +{ + namespace Internals + { + class OpenGLColorTextureProgram : public boost::noncopyable + { + private: + OpenGLTextureProgram program_; + + public: + OpenGLColorTextureProgram(OpenGL::IOpenGLContext& context); + + void Apply(OpenGL::OpenGLTexture& texture, + const AffineTransform2D& transform, + bool useAlpha); + }; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2D/Internals/OpenGLFloatTextureProgram.cpp Fri Apr 26 12:05:38 2019 +0200 @@ -0,0 +1,146 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include "OpenGLFloatTextureProgram.h" + +#include <Core/OrthancException.h> +#include <Core/Images/Image.h> +#include <Core/Images/ImageProcessing.h> + + +static const char* FRAGMENT_SHADER = + "uniform float u_offset; \n" + "uniform float u_slope; \n" + "uniform float u_windowCenter; \n" + "uniform float u_windowWidth; \n" + "uniform sampler2D u_texture; \n" + "varying vec2 v_texcoord; \n" + "void main() \n" + "{ \n" + " vec4 t = texture2D(u_texture, v_texcoord); \n" + " float v = (t.r * 256.0 + t.g) * 256.0; \n" + " v = v * u_slope + u_offset; \n" // (*) + " float a = u_windowCenter - u_windowWidth; \n" + " float dy = 1.0 / (2.0 * u_windowWidth); \n" + " if (v <= a) \n" + " v = 0.0; \n" + " else \n" + " { \n" + " v = (v - a) * dy; \n" + " if (v >= 1.0) \n" + " v = 1.0; \n" + " } \n" + " gl_FragColor = vec4(v, v, v, 1); \n" + "}"; + + +namespace OrthancStone +{ + namespace Internals + { + OpenGLFloatTextureProgram::OpenGLFloatTextureProgram(OpenGL::IOpenGLContext& context) : + program_(context, FRAGMENT_SHADER) + { + } + + + OpenGLFloatTextureProgram::Data::Data(const Orthanc::ImageAccessor& texture, + bool isLinearInterpolation) + { + if (texture.GetFormat() != Orthanc::PixelFormat_Float32) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_IncompatibleImageFormat); + } + + float minValue, maxValue; + Orthanc::ImageProcessing::GetMinMaxFloatValue(minValue, maxValue, texture); + + offset_ = minValue; + + if (LinearAlgebra::IsCloseToZero(maxValue - minValue)) + { + slope_ = 1; + } + else + { + slope_ = (maxValue - minValue) / 65536.0f; + assert(!LinearAlgebra::IsCloseToZero(slope_)); + } + + const unsigned int width = texture.GetWidth(); + const unsigned int height = texture.GetHeight(); + + Orthanc::Image converted(Orthanc::PixelFormat_RGB24, width, height, true); + + for (unsigned int y = 0; y < height; y++) + { + const float *p = reinterpret_cast<const float*>(texture.GetConstRow(y)); + uint8_t *q = reinterpret_cast<uint8_t*>(converted.GetRow(y)); + + for (unsigned int x = 0; x < width; x++) + { + /** + * At (*), the floating-point "value" is reconstructed as + * "value = texture * slope + offset". + * <=> texture = (value - offset) / slope + **/ + + float texture = (*p - offset_) / slope_; + if (texture < 0) + { + texture = 0; + } + else if (texture >= 65535.0f) + { + texture = 65535.0f; + } + + uint16_t t = static_cast<uint16_t>(texture); + + q[0] = t / 256; // red + q[1] = t % 256; // green + q[2] = 0; // blue is unused + + p++; + q += 3; + } + } + + texture_.Load(converted, isLinearInterpolation); + } + + + void OpenGLFloatTextureProgram::Apply(Data& data, + const AffineTransform2D& transform, + float windowCenter, + float windowWidth) + { + OpenGLTextureProgram::Execution execution(program_, data.GetTexture(), transform); + + glUniform1f(execution.GetUniformLocation("u_slope"), data.GetSlope()); + glUniform1f(execution.GetUniformLocation("u_offset"), data.GetOffset()); + glUniform1f(execution.GetUniformLocation("u_windowCenter"), windowCenter); + glUniform1f(execution.GetUniformLocation("u_windowWidth"), windowWidth); + + execution.DrawTriangles(); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2D/Internals/OpenGLFloatTextureProgram.h Fri Apr 26 12:05:38 2019 +0200 @@ -0,0 +1,71 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include "OpenGLTextureProgram.h" + +namespace OrthancStone +{ + namespace Internals + { + class OpenGLFloatTextureProgram : public boost::noncopyable + { + private: + OpenGLTextureProgram program_; + + public: + OpenGLFloatTextureProgram(OpenGL::IOpenGLContext& context); + + class Data : public boost::noncopyable + { + private: + OpenGL::OpenGLTexture texture_; + float offset_; + float slope_; + + public: + Data(const Orthanc::ImageAccessor& texture, + bool isLinearInterpolation); + + float GetOffset() const + { + return offset_; + } + + float GetSlope() const + { + return slope_; + } + + OpenGL::OpenGLTexture& GetTexture() + { + return texture_; + } + }; + + void Apply(Data& data, + const AffineTransform2D& transform, + float windowCenter, + float windowWidth); + }; + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2D/Internals/OpenGLTextureProgram.cpp Fri Apr 26 12:05:38 2019 +0200 @@ -0,0 +1,120 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#include "OpenGLTextureProgram.h" + +static const unsigned int COMPONENTS = 2; +static const unsigned int COUNT = 6; // 2 triangles in 2D + +static const char* VERTEX_SHADER = + "attribute vec2 a_texcoord; \n" + "attribute vec4 a_position; \n" + "uniform mat4 u_matrix; \n" + "varying vec2 v_texcoord; \n" + "void main() \n" + "{ \n" + " gl_Position = u_matrix * a_position; \n" + " v_texcoord = a_texcoord; \n" + "}"; + + +namespace OrthancStone +{ + namespace Internals + { + void OpenGLTextureProgram::InitializeExecution(OpenGL::OpenGLTexture& texture, + const AffineTransform2D& transform) + { + context_.MakeCurrent(); + program_->Use(); + + AffineTransform2D scale = AffineTransform2D::CreateScaling + (texture.GetWidth(), texture.GetHeight()); + + AffineTransform2D t = AffineTransform2D::Combine(transform, scale); + + float m[16]; + t.ConvertToOpenGLMatrix(m, context_.GetCanvasWidth(), context_.GetCanvasHeight()); + + texture.Bind(program_->GetUniformLocation("u_texture")); + glUniformMatrix4fv(program_->GetUniformLocation("u_matrix"), 1, GL_FALSE, m); + + glBindBuffer(GL_ARRAY_BUFFER, buffers_[0]); + glEnableVertexAttribArray(positionLocation_); + glVertexAttribPointer(positionLocation_, COMPONENTS, GL_FLOAT, GL_FALSE, 0, 0); + + glBindBuffer(GL_ARRAY_BUFFER, buffers_[1]); + glEnableVertexAttribArray(textureLocation_); + glVertexAttribPointer(textureLocation_, COMPONENTS, GL_FLOAT, GL_FALSE, 0, 0); + } + + + void OpenGLTextureProgram::FinalizeExecution() + { + glDisableVertexAttribArray(positionLocation_); + glDisableVertexAttribArray(textureLocation_); + } + + + OpenGLTextureProgram::OpenGLTextureProgram(OpenGL::IOpenGLContext& context, + const char* fragmentShader) : + context_(context) + { + static const float POSITIONS[COMPONENTS * COUNT] = { + 0, 0, + 0, 1, + 1, 0, + 1, 0, + 0, 1, + 1, 1 + }; + + context_.MakeCurrent(); + + program_.reset(new OpenGL::OpenGLProgram); + program_->CompileShaders(VERTEX_SHADER, fragmentShader); + + positionLocation_ = program_->GetAttributeLocation("a_position"); + textureLocation_ = program_->GetAttributeLocation("a_texcoord"); + + glGenBuffers(2, buffers_); + + glBindBuffer(GL_ARRAY_BUFFER, buffers_[0]); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * COMPONENTS * COUNT, POSITIONS, GL_STATIC_DRAW); + + glBindBuffer(GL_ARRAY_BUFFER, buffers_[1]); + glBufferData(GL_ARRAY_BUFFER, sizeof(float) * COMPONENTS * COUNT, POSITIONS, GL_STATIC_DRAW); + } + + + OpenGLTextureProgram::~OpenGLTextureProgram() + { + context_.MakeCurrent(); + glDeleteBuffers(2, buffers_); + } + + + void OpenGLTextureProgram::Execution::DrawTriangles() + { + glDrawArrays(GL_TRIANGLES, 0, COUNT); + } + } +}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/Scene2D/Internals/OpenGLTextureProgram.h Fri Apr 26 12:05:38 2019 +0200 @@ -0,0 +1,81 @@ +/** + * Stone of Orthanc + * Copyright (C) 2012-2016 Sebastien Jodogne, Medical Physics + * Department, University Hospital of Liege, Belgium + * Copyright (C) 2017-2019 Osimis S.A., Belgium + * + * This program is free software: you can redistribute it and/or + * modify it under the terms of the GNU Affero General Public License + * as published by the Free Software Foundation, either version 3 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see <http://www.gnu.org/licenses/>. + **/ + + +#pragma once + +#include "../../OpenGL/IOpenGLContext.h" +#include "../../OpenGL/OpenGLProgram.h" +#include "../../OpenGL/OpenGLTexture.h" +#include "../../Toolbox/AffineTransform2D.h" + +namespace OrthancStone +{ + namespace Internals + { + class OpenGLTextureProgram : public boost::noncopyable + { + private: + OpenGL::IOpenGLContext& context_; + std::auto_ptr<OpenGL::OpenGLProgram> program_; + GLint positionLocation_; + GLint textureLocation_; + GLuint buffers_[2]; + + void InitializeExecution(OpenGL::OpenGLTexture& texture, + const AffineTransform2D& transform); + + void FinalizeExecution(); + + public: + OpenGLTextureProgram(OpenGL::IOpenGLContext& context, + const char* fragmentShader); + + ~OpenGLTextureProgram(); + + class Execution : public boost::noncopyable + { + private: + OpenGLTextureProgram& that_; + + public: + Execution(OpenGLTextureProgram& that, + OpenGL::OpenGLTexture& texture, + const AffineTransform2D& transform) : + that_(that) + { + that_.InitializeExecution(texture, transform); + } + + ~Execution() + { + that_.FinalizeExecution(); + } + + void DrawTriangles(); + + GLint GetUniformLocation(const std::string& name) + { + return that_.program_->GetUniformLocation(name); + } + }; + }; + } +}
--- a/Resources/CMake/OrthancStoneConfiguration.cmake Fri Apr 26 11:33:57 2019 +0200 +++ b/Resources/CMake/OrthancStoneConfiguration.cmake Fri Apr 26 12:05:38 2019 +0200 @@ -389,8 +389,9 @@ ${ORTHANC_STONE_ROOT}/Framework/OpenGL/OpenGLProgram.cpp ${ORTHANC_STONE_ROOT}/Framework/OpenGL/OpenGLShader.cpp ${ORTHANC_STONE_ROOT}/Framework/OpenGL/OpenGLTexture.cpp - ${ORTHANC_STONE_ROOT}/Framework/OpenGL/TextOpenGLProgram.cpp - ${ORTHANC_STONE_ROOT}/Framework/Scene2D/Internals/ColorTextureOpenGLProgram.cpp + ${ORTHANC_STONE_ROOT}/Framework/Scene2D/Internals/OpenGLFloatTextureProgram.cpp + ${ORTHANC_STONE_ROOT}/Framework/Scene2D/Internals/OpenGLColorTextureProgram.cpp + ${ORTHANC_STONE_ROOT}/Framework/Scene2D/Internals/OpenGLTextureProgram.cpp ) endif()