# HG changeset patch # User Sebastien Jodogne # Date 1555682805 -7200 # Node ID fadacfbf5538caf6c2efa2e956e247d00bc39b0d # Parent 21fd70df3fc9558813bba550db6747459aa3d734 OpenGL programs and textures diff -r 21fd70df3fc9 -r fadacfbf5538 Framework/OpenGL/OpenGLProgram.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/OpenGL/OpenGLProgram.cpp Fri Apr 19 16:06:45 2019 +0200 @@ -0,0 +1,103 @@ +/** + * 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 . + **/ + + +#include "OpenGLProgram.h" + +#include "OpenGLShader.h" + +#include + + +namespace OrthancStone +{ + namespace OpenGL + { + OpenGLProgram::OpenGLProgram() + { + program_ = glCreateProgram(); + if (program_ == 0) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, + "Cannot create an OpenGL program"); + } + } + + + OpenGLProgram::~OpenGLProgram() + { + assert(program_ != 0); + glDeleteProgram(program_); + } + + + void OpenGLProgram::Use() + { + glUseProgram(program_); + } + + + void OpenGLProgram::CompileShaders(const std::string& vertexCode, + const std::string& fragmentCode) + { + assert(program_ != 0); + + OpenGLShader vertexShader(GL_VERTEX_SHADER, vertexCode); + OpenGLShader fragmentShader(GL_FRAGMENT_SHADER, fragmentCode); + + glAttachShader(program_, vertexShader.Release()); + glAttachShader(program_, fragmentShader.Release()); + glLinkProgram(program_); + glValidateProgram(program_); + } + + + GLint OpenGLProgram::GetUniformLocation(const std::string& name) + { + GLint location = glGetUniformLocation(program_, name.c_str()); + + if (location == -1) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentItem, + "Inexistent uniform variable in shader: " + name); + } + else + { + return location; + } + } + + + GLint OpenGLProgram::GetAttributeLocation(const std::string& name) + { + GLint location = glGetAttribLocation(program_, name.c_str()); + + if (location == -1) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_InexistentItem, + "Inexistent attribute in shader: " + name); + } + else + { + return location; + } + } + } +} diff -r 21fd70df3fc9 -r fadacfbf5538 Framework/OpenGL/OpenGLProgram.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/OpenGL/OpenGLProgram.h Fri Apr 19 16:06:45 2019 +0200 @@ -0,0 +1,62 @@ +/** + * 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 . + **/ + + +#pragma once + +#if !defined(ORTHANC_ENABLE_OPENGL) +# error The macro ORTHANC_ENABLE_OPENGL must be defined +#endif + +#if ORTHANC_ENABLE_OPENGL != 1 +# error Support for OpenGL is disabled +#endif + +#include +#include +#include + +namespace OrthancStone +{ + namespace OpenGL + { + class OpenGLProgram : public boost::noncopyable + { + private: + GLuint program_; + + public: + // WARNING: A global OpenGL context must be active to create this object! + OpenGLProgram(); + + ~OpenGLProgram(); + + void Use(); + + // WARNING: A global OpenGL context must be active to run this method! + void CompileShaders(const std::string& vertexCode, + const std::string& fragmentCode); + + GLint GetUniformLocation(const std::string& name); + + GLint GetAttributeLocation(const std::string& name); + }; + } +} diff -r 21fd70df3fc9 -r fadacfbf5538 Framework/OpenGL/OpenGLShader.cpp --- a/Framework/OpenGL/OpenGLShader.cpp Fri Apr 19 15:57:46 2019 +0200 +++ b/Framework/OpenGL/OpenGLShader.cpp Fri Apr 19 16:06:45 2019 +0200 @@ -78,17 +78,6 @@ } - OpenGLShader::OpenGLShader(GLenum type, - Orthanc::EmbeddedResources::FileResourceId resource) - { - std::string content; - Orthanc::EmbeddedResources::GetFileResource(content, resource); - - shader_ = CompileShader(type, content); - isValid_ = true; - } - - OpenGLShader::~OpenGLShader() { if (isValid_) diff -r 21fd70df3fc9 -r fadacfbf5538 Framework/OpenGL/OpenGLShader.h --- a/Framework/OpenGL/OpenGLShader.h Fri Apr 19 15:57:46 2019 +0200 +++ b/Framework/OpenGL/OpenGLShader.h Fri Apr 19 16:06:45 2019 +0200 @@ -21,7 +21,6 @@ #pragma once - #if !defined(ORTHANC_ENABLE_OPENGL) # error The macro ORTHANC_ENABLE_OPENGL must be defined #endif @@ -30,8 +29,7 @@ # error Support for OpenGL is disabled #endif -#include - +#include #include #include @@ -49,9 +47,6 @@ OpenGLShader(GLenum type, const std::string& source); - OpenGLShader(GLenum type, - Orthanc::EmbeddedResources::FileResourceId resource); - ~OpenGLShader(); bool IsValid() const diff -r 21fd70df3fc9 -r fadacfbf5538 Framework/OpenGL/OpenGLTexture.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/OpenGL/OpenGLTexture.cpp Fri Apr 19 16:06:45 2019 +0200 @@ -0,0 +1,113 @@ +/** + * 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 . + **/ + + +#include "OpenGLTexture.h" + +#include + +namespace OrthancStone +{ + namespace OpenGL + { + OpenGLTexture::OpenGLTexture() : + width_(0), + height_(0) + { + // Generate a texture object + glGenTextures(1, &texture_); + if (texture_ == 0) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, + "Cannot create an OpenGL program"); + } + } + + + OpenGLTexture::~OpenGLTexture() + { + assert(texture_ != 0); + glDeleteTextures(1, &texture_); + } + + + void OpenGLTexture::Load(const Orthanc::ImageAccessor& image, + bool isLinearInterpolation) + { + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Disable byte-alignment restriction + + if (image.GetPitch() != image.GetBytesPerPixel() * image.GetWidth()) + { + throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, + "Unsupported non-zero padding"); + } + + // Bind it + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture_); + + GLenum sourceFormat, internalFormat; + + switch (image.GetFormat()) + { + case Orthanc::PixelFormat_Grayscale8: + sourceFormat = GL_RED; + internalFormat = GL_RED; + break; + + case Orthanc::PixelFormat_RGB24: + sourceFormat = GL_RGB; + internalFormat = GL_RGBA; + break; + + case Orthanc::PixelFormat_RGBA32: + sourceFormat = GL_RGBA; + internalFormat = GL_RGBA; + break; + + default: + throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, + "No support for this format in OpenGL textures: " + + std::string(EnumerationToString(image.GetFormat()))); + } + + width_ = image.GetWidth(); + height_ = image.GetHeight(); + + GLint interpolation = (isLinearInterpolation ? GL_LINEAR : GL_NEAREST); + + // Load the texture from the image buffer + glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, image.GetWidth(), image.GetHeight(), + 0, sourceFormat, GL_UNSIGNED_BYTE, image.GetBuffer()); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, interpolation); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, interpolation); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } + + + void OpenGLTexture::Bind(GLint location) + { + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, texture_); + glUniform1i(location, 0 /* texture unit */); + } + } +} diff -r 21fd70df3fc9 -r fadacfbf5538 Framework/OpenGL/OpenGLTexture.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Framework/OpenGL/OpenGLTexture.h Fri Apr 19 16:06:45 2019 +0200 @@ -0,0 +1,70 @@ +/** + * 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 . + **/ + + +#pragma once + +#if !defined(ORTHANC_ENABLE_OPENGL) +# error The macro ORTHANC_ENABLE_OPENGL must be defined +#endif + +#if ORTHANC_ENABLE_OPENGL != 1 +# error Support for OpenGL is disabled +#endif + +#include + +#include +#include + + +namespace OrthancStone +{ + namespace OpenGL + { + class OpenGLTexture : public boost::noncopyable + { + private: + GLuint texture_; + unsigned int width_; + unsigned int height_; + + public: + OpenGLTexture(); + + ~OpenGLTexture(); + + unsigned int GetWidth() const + { + return width_; + } + + unsigned int GetHeight() const + { + return height_; + } + + void Load(const Orthanc::ImageAccessor& image, + bool isLinearInterpolation); + + void Bind(GLint location); + }; + } +} diff -r 21fd70df3fc9 -r fadacfbf5538 Resources/CMake/OrthancStoneConfiguration.cmake --- a/Resources/CMake/OrthancStoneConfiguration.cmake Fri Apr 19 15:57:46 2019 +0200 +++ b/Resources/CMake/OrthancStoneConfiguration.cmake Fri Apr 19 16:06:45 2019 +0200 @@ -377,7 +377,9 @@ if (ENABLE_OPENGL) list(APPEND ORTHANC_STONE_SOURCES ${ORTHANC_STONE_ROOT}/Framework/Fonts/OpenGLTextCoordinates.cpp + ${ORTHANC_STONE_ROOT}/Framework/OpenGL/OpenGLProgram.cpp ${ORTHANC_STONE_ROOT}/Framework/OpenGL/OpenGLShader.cpp + ${ORTHANC_STONE_ROOT}/Framework/OpenGL/OpenGLTexture.cpp ) endif()