comparison OrthancStone/Sources/OpenGL/ImageProcessingProgram.cpp @ 2061:6ea5f40ea0e9 deep-learning

added ImageProcessingProgram
author Sebastien Jodogne <s.jodogne@gmail.com>
date Wed, 03 May 2023 16:34:34 +0200
parents
children 4e31d76c7ecd
comparison
equal deleted inserted replaced
2060:86e0e92a2e0d 2061:6ea5f40ea0e9
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-2022 Osimis S.A., Belgium
6 * Copyright (C) 2021-2022 Sebastien Jodogne, ICTEAM UCLouvain, Belgium
7 *
8 * This program is free software: you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation, either version 3 of
11 * the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
17 *
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this program. If not, see
20 * <http://www.gnu.org/licenses/>.
21 **/
22
23
24 #include "ImageProcessingProgram.h"
25
26 #include "OpenGLFramebuffer.h"
27
28 #include <OrthancException.h>
29
30
31 static const unsigned int DIMENSIONS = 2; // Number of dimensions (we draw in 2D)
32 static const unsigned int VERTICES = 6; // 2 triangles in 2D (each triangle has 3 vertices)
33
34
35 static const float TRIANGLES[DIMENSIONS * VERTICES] = {
36 // First triangle
37 -1.0f, -1.0f,
38 1.0f, -1.0f,
39 -1.0f, 1.0f,
40 // Second triangle
41 -1.0f, 1.0f,
42 1.0f, -1.0f,
43 1.0f, 1.0f
44 };
45
46
47 /**
48 * "varying" indicates variables that are shader by the vertex shader
49 * and the fragment shader. The reason for "v_position" is that
50 * "a_position" (position in the target frame buffer) ranges from -1
51 * to 1, whereas texture samplers range from 0 to 1.
52 **/
53 static const char* VERTEX_SHADER =
54 "in vec2 a_position; \n"
55 "out vec2 v_position; \n"
56 "void main() { \n"
57 " v_position = (a_position + 1.0) / 2.0; \n"
58 " gl_Position = vec4(a_position, 0, 1.0); \n"
59 "} \n";
60
61
62 namespace OrthancStone
63 {
64 namespace OpenGL
65 {
66 void ImageProcessingProgram::SetupPosition()
67 {
68 glBindBuffer(GL_ARRAY_BUFFER, quad_vertexbuffer);
69 glBufferData(GL_ARRAY_BUFFER, sizeof(float) * DIMENSIONS * VERTICES, TRIANGLES, GL_STATIC_DRAW);
70 GLint positionLocation = program_.GetAttributeLocation("a_position");
71 glVertexAttribPointer(positionLocation, 2, GL_FLOAT, GL_FALSE, 0, 0);
72 glEnableVertexAttribArray(positionLocation);
73 }
74
75
76 ImageProcessingProgram::ImageProcessingProgram(IOpenGLContext& context,
77 const std::string& fragmentShader) :
78 program_(context),
79 quad_vertexbuffer(0)
80 {
81 if (context.IsContextLost())
82 {
83 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError,
84 "OpenGL context has been lost");
85 }
86
87 context.MakeCurrent();
88
89 std::string version;
90
91 #if ORTHANC_ENABLE_WASM == 1
92 /**
93 * "#version 300 es" corresponds to:
94 * - OpenGL ES version 3.0: https://registry.khronos.org/OpenGL-Refpages/es3.0/
95 * - WebGL version 2.0
96 * - GLSL ES version 3.00.6
97 * - Based on version GLSL version 3.0
98 *
99 * Explanation for "highp":
100 * https://emscripetn.org/docs/optimizing/Optimizing-WebGL.html
101 * https://webglfundamentals.org/webgl/lessons/webgl-qna-when-to-choose-highp--mediump--lowp-in-shaders.html
102 **/
103 version = ("#version 300 es\n"
104 "precision highp float;\n"
105 "precision highp sampler2D;\n"
106 "precision highp sampler2DArray;\n");
107 #else
108 /**
109 * "#version 130" corresponds to:
110 * - OpenGL version 3.0
111 * - GLSL version 1.30.10
112 **/
113 version = "#version 130\n";
114 #endif
115
116 program_.CompileShaders(version + VERTEX_SHADER, version + fragmentShader);
117
118 glGenBuffers(1, &quad_vertexbuffer);
119 if (quad_vertexbuffer == 0)
120 {
121 throw Orthanc::OrthancException(Orthanc::ErrorCode_InternalError,
122 "Cannot create OpenGL buffer");
123 }
124 }
125
126
127 ImageProcessingProgram::~ImageProcessingProgram()
128 {
129 glDeleteBuffers(1, &quad_vertexbuffer);
130 }
131
132
133 void ImageProcessingProgram::Use(OpenGLTexture& target,
134 OpenGLFramebuffer& framebuffer,
135 bool checkStatus)
136 {
137 program_.Use(checkStatus);
138 framebuffer.SetTarget(target);
139 SetupPosition();
140 }
141
142
143 void ImageProcessingProgram::Use(OpenGLTextureArray& target,
144 unsigned int targetLayer,
145 OpenGLFramebuffer& framebuffer,
146 bool checkStatus)
147 {
148 program_.Use(checkStatus);
149 framebuffer.SetTarget(target, targetLayer);
150 SetupPosition();
151 }
152
153
154 void ImageProcessingProgram::Render()
155 {
156 glClearColor(0.0, 0.0, 0.0, 1.0);
157 glClear(GL_COLOR_BUFFER_BIT);
158
159 #if 1
160 glDrawArrays(GL_TRIANGLES, 0, VERTICES);
161 #else
162 // Simpler, but not available in WebGL
163 glBegin(GL_QUADS);
164 glVertex2f(-1, 1); // vertex 1
165 glVertex2f(-1, -1); // vertex 2
166 glVertex2f( 1, -1); // vertex 3
167 glVertex2f( 1, 1); // vertex 4
168 glEnd();
169 #endif
170
171 ORTHANC_OPENGL_CHECK("glDrawArrays()");
172 }
173 }
174 }