Mercurial > hg > orthanc-stone
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 } |