comparison Framework/OpenGL/OpenGLTexture.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 97926984d5d0
children 6a9300ecfa13
comparison
equal deleted inserted replaced
946:dbe3e1e47019 947:1091b2adeb5a
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. 18 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 **/ 19 **/
20 20
21 21
22 #include "OpenGLTexture.h" 22 #include "OpenGLTexture.h"
23 #include "IOpenGLContext.h"
23 24
24 #include <Core/OrthancException.h> 25 #include <Core/OrthancException.h>
25 26
26 namespace OrthancStone 27 namespace OrthancStone
27 { 28 {
28 namespace OpenGL 29 namespace OpenGL
29 { 30 {
30 OpenGLTexture::OpenGLTexture() : 31 OpenGLTexture::OpenGLTexture(OpenGL::IOpenGLContext& context)
31 width_(0), 32 : width_(0)
32 height_(0) 33 , height_(0)
34 , context_(context)
33 { 35 {
34 // Generate a texture object 36 if (!context_.IsContextLost())
35 glGenTextures(1, &texture_);
36 if (texture_ == 0)
37 { 37 {
38 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError, 38 // context is made current externally. Let's check this!
39 "Cannot create an OpenGL program"); 39 ORTHANC_CHECK_CURRENT_CONTEXT(context_);
40 // Generate a texture object
41 glGenTextures(1, &texture_);
42 if (texture_ == 0)
43 {
44 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError,
45 "Cannot create an OpenGL program");
46 }
40 } 47 }
41 } 48 }
42 49
43
44 OpenGLTexture::~OpenGLTexture() 50 OpenGLTexture::~OpenGLTexture()
45 { 51 {
46 assert(texture_ != 0); 52 try
47 glDeleteTextures(1, &texture_); 53 {
54 if (!context_.IsContextLost())
55 {
56 // context is made current externally. Let's check this!
57 ORTHANC_CHECK_CURRENT_CONTEXT(context_);
58 assert(texture_ != 0);
59 ORTHANC_OPENGL_TRACE_CURRENT_CONTEXT("About to call glDeleteTextures");
60 glDeleteTextures(1, &texture_);
61 }
62 }
63 catch (const Orthanc::OrthancException& e)
64 {
65 if (e.HasDetails())
66 {
67 LOG(ERROR) << "OrthancException in ~OpenGLTexture: " << e.What() << " Details: " << e.GetDetails();
68 }
69 else
70 {
71 LOG(ERROR) << "OrthancException in ~OpenGLTexture: " << e.What();
72 }
73 }
74 catch (const std::exception& e)
75 {
76 LOG(ERROR) << "std::exception in ~OpenGLTexture: " << e.what();
77 }
78 catch (...)
79 {
80 LOG(ERROR) << "Unknown exception in ~OpenGLTexture";
81 }
48 } 82 }
49
50 83
51 void OpenGLTexture::Load(const Orthanc::ImageAccessor& image, 84 void OpenGLTexture::Load(const Orthanc::ImageAccessor& image,
52 bool isLinearInterpolation) 85 bool isLinearInterpolation)
53 { 86 {
54 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Disable byte-alignment restriction 87 // context is made current externally. Let's check this!
55 88 ORTHANC_CHECK_CURRENT_CONTEXT(context_);
56 if (image.GetPitch() != image.GetBytesPerPixel() * image.GetWidth()) 89 if (!context_.IsContextLost())
57 { 90 {
58 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, 91 glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // Disable byte-alignment restriction
59 "Unsupported non-zero padding");
60 }
61 92
62 // Bind it 93 if (image.GetPitch() != image.GetBytesPerPixel() * image.GetWidth())
63 glActiveTexture(GL_TEXTURE0); 94 {
64 glBindTexture(GL_TEXTURE_2D, texture_); 95 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented,
96 "Unsupported non-zero padding");
97 }
65 98
66 GLenum sourceFormat, internalFormat; 99 // Bind it
100 glActiveTexture(GL_TEXTURE0);
101 glBindTexture(GL_TEXTURE_2D, texture_);
67 102
68 switch (image.GetFormat()) 103 GLenum sourceFormat, internalFormat;
69 { 104
105 switch (image.GetFormat())
106 {
70 case Orthanc::PixelFormat_Grayscale8: 107 case Orthanc::PixelFormat_Grayscale8:
71 sourceFormat = GL_RED; 108 sourceFormat = GL_RED;
72 internalFormat = GL_RED; 109 internalFormat = GL_RED;
73 break; 110 break;
74 111
82 internalFormat = GL_RGBA; 119 internalFormat = GL_RGBA;
83 break; 120 break;
84 121
85 default: 122 default:
86 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented, 123 throw Orthanc::OrthancException(Orthanc::ErrorCode_NotImplemented,
87 "No support for this format in OpenGL textures: " + 124 "No support for this format in OpenGL textures: " +
88 std::string(EnumerationToString(image.GetFormat()))); 125 std::string(EnumerationToString(image.GetFormat())));
126 }
127
128 width_ = image.GetWidth();
129 height_ = image.GetHeight();
130
131 GLint interpolation = (isLinearInterpolation ? GL_LINEAR : GL_NEAREST);
132
133 // Load the texture from the image buffer
134 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, image.GetWidth(), image.GetHeight(),
135 0, sourceFormat, GL_UNSIGNED_BYTE, image.GetBuffer());
136 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, interpolation);
137 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, interpolation);
138 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
139 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
89 } 140 }
90
91 width_ = image.GetWidth();
92 height_ = image.GetHeight();
93
94 GLint interpolation = (isLinearInterpolation ? GL_LINEAR : GL_NEAREST);
95
96 // Load the texture from the image buffer
97 glTexImage2D(GL_TEXTURE_2D, 0, internalFormat, image.GetWidth(), image.GetHeight(),
98 0, sourceFormat, GL_UNSIGNED_BYTE, image.GetBuffer());
99 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, interpolation);
100 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, interpolation);
101 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
102 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
103 } 141 }
104 142
105 143
106 void OpenGLTexture::Bind(GLint location) 144 void OpenGLTexture::Bind(GLint location)
107 { 145 {