Mercurial > hg > orthanc-stone
comparison Framework/OpenGL/TextOpenGLProgram.cpp @ 585:b9ce24c606ae
TextSceneLayer
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Fri, 19 Apr 2019 17:57:58 +0200 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
584:434ceeb0bcab | 585:b9ce24c606ae |
---|---|
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-2019 Osimis S.A., Belgium | |
6 * | |
7 * This program is free software: you can redistribute it and/or | |
8 * modify it under the terms of the GNU Affero General Public License | |
9 * as published by the Free Software Foundation, either version 3 of | |
10 * the License, or (at your option) any later version. | |
11 * | |
12 * This program is distributed in the hope that it will be useful, but | |
13 * WITHOUT ANY WARRANTY; without even the implied warranty of | |
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
15 * Affero General Public License for more details. | |
16 * | |
17 * You should have received a copy of the GNU Affero General Public License | |
18 * along with this program. If not, see <http://www.gnu.org/licenses/>. | |
19 **/ | |
20 | |
21 | |
22 #include "TextOpenGLProgram.h" | |
23 | |
24 #include "../Fonts/OpenGLTextCoordinates.h" | |
25 | |
26 #include <Core/OrthancException.h> | |
27 | |
28 | |
29 namespace OrthancStone | |
30 { | |
31 namespace OpenGL | |
32 { | |
33 TextOpenGLProgram::TextOpenGLProgram(IOpenGLContext& context) : | |
34 context_(context) | |
35 { | |
36 static const char* VERTEX_SHADER = | |
37 "attribute vec2 a_texcoord; \n" | |
38 "attribute vec4 a_position; \n" | |
39 "uniform mat4 u_matrix; \n" | |
40 "varying vec2 v_texcoord; \n" | |
41 "void main() \n" | |
42 "{ \n" | |
43 " gl_Position = u_matrix * a_position; \n" | |
44 " v_texcoord = a_texcoord; \n" | |
45 "}"; | |
46 | |
47 static const char* FRAGMENT_SHADER = | |
48 "uniform sampler2D u_texture; \n" | |
49 "uniform vec3 u_color; \n" | |
50 "varying vec2 v_texcoord; \n" | |
51 "void main() \n" | |
52 "{ \n" | |
53 " vec4 v = texture2D(u_texture, v_texcoord); \n" | |
54 " gl_FragColor = vec4(u_color * v.w, v.w); \n" // Premultiplied alpha | |
55 "}"; | |
56 | |
57 context_.MakeCurrent(); | |
58 | |
59 program_.reset(new OpenGLProgram); | |
60 program_->CompileShaders(VERTEX_SHADER, FRAGMENT_SHADER); | |
61 | |
62 positionLocation_ = program_->GetAttributeLocation("a_position"); | |
63 textureLocation_ = program_->GetAttributeLocation("a_texcoord"); | |
64 } | |
65 | |
66 | |
67 TextOpenGLProgram::Data::Data(IOpenGLContext& context, | |
68 const GlyphTextureAlphabet& alphabet, | |
69 const TextSceneLayer& layer) : | |
70 context_(context), | |
71 red_(layer.GetRedAsFloat()), | |
72 green_(layer.GetGreenAsFloat()), | |
73 blue_(layer.GetBlueAsFloat()), | |
74 x_(layer.GetX()), | |
75 y_(layer.GetY()), | |
76 border_(layer.GetBorder()), | |
77 anchor_(layer.GetAnchor()) | |
78 { | |
79 OpenGLTextCoordinates coordinates(alphabet, layer.GetText()); | |
80 textWidth_ = coordinates.GetTextWidth(); | |
81 textHeight_ = coordinates.GetTextHeight(); | |
82 | |
83 if (coordinates.IsEmpty()) | |
84 { | |
85 coordinatesCount_ = 0; | |
86 } | |
87 else | |
88 { | |
89 coordinatesCount_ = coordinates.GetRenderingCoords().size(); | |
90 | |
91 context_.MakeCurrent(); | |
92 glGenBuffers(2, buffers_); | |
93 | |
94 glBindBuffer(GL_ARRAY_BUFFER, buffers_[0]); | |
95 glBufferData(GL_ARRAY_BUFFER, sizeof(float) * coordinatesCount_, | |
96 &coordinates.GetRenderingCoords() [0], GL_STATIC_DRAW); | |
97 | |
98 glBindBuffer(GL_ARRAY_BUFFER, buffers_[1]); | |
99 glBufferData(GL_ARRAY_BUFFER, sizeof(float) * coordinatesCount_, | |
100 &coordinates.GetTextureCoords() [0], GL_STATIC_DRAW); | |
101 } | |
102 } | |
103 | |
104 | |
105 TextOpenGLProgram::Data::~Data() | |
106 { | |
107 if (!IsEmpty()) | |
108 { | |
109 context_.MakeCurrent(); | |
110 glDeleteBuffers(2, buffers_); | |
111 } | |
112 } | |
113 | |
114 | |
115 GLuint TextOpenGLProgram::Data::GetSceneLocationsBuffer() const | |
116 { | |
117 if (IsEmpty()) | |
118 { | |
119 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
120 } | |
121 else | |
122 { | |
123 return buffers_[0]; | |
124 } | |
125 } | |
126 | |
127 | |
128 GLuint TextOpenGLProgram::Data::GetTextureLocationsBuffer() const | |
129 { | |
130 if (IsEmpty()) | |
131 { | |
132 throw Orthanc::OrthancException(Orthanc::ErrorCode_BadSequenceOfCalls); | |
133 } | |
134 else | |
135 { | |
136 return buffers_[1]; | |
137 } | |
138 } | |
139 | |
140 | |
141 void TextOpenGLProgram::Apply(OpenGLTexture& fontTexture, | |
142 const Data& data, | |
143 const AffineTransform2D& transform) | |
144 { | |
145 if (!data.IsEmpty()) | |
146 { | |
147 context_.MakeCurrent(); | |
148 program_->Use(); | |
149 | |
150 double dx, dy; // In pixels | |
151 ComputeAnchorTranslation(dx, dy, data.GetAnchor(), data.GetTextWidth(), data.GetTextHeight(), data.GetBorder()); | |
152 | |
153 double x = data.GetX(); | |
154 double y = data.GetY(); | |
155 transform.Apply(x, y); | |
156 | |
157 const AffineTransform2D t = AffineTransform2D::CreateOffset(x + dx, y + dy); | |
158 | |
159 float m[16]; | |
160 t.ConvertToOpenGLMatrix(m, context_.GetCanvasWidth(), context_.GetCanvasHeight()); | |
161 | |
162 fontTexture.Bind(program_->GetUniformLocation("u_texture")); | |
163 glUniformMatrix4fv(program_->GetUniformLocation("u_matrix"), 1, GL_FALSE, m); | |
164 glUniform3f(program_->GetUniformLocation("u_color"), | |
165 data.GetRed(), data.GetGreen(), data.GetBlue()); | |
166 | |
167 glBindBuffer(GL_ARRAY_BUFFER, data.GetSceneLocationsBuffer()); | |
168 glEnableVertexAttribArray(positionLocation_); | |
169 glVertexAttribPointer(positionLocation_, COMPONENTS, GL_FLOAT, GL_FALSE, 0, 0); | |
170 | |
171 glBindBuffer(GL_ARRAY_BUFFER, data.GetTextureLocationsBuffer()); | |
172 glEnableVertexAttribArray(textureLocation_); | |
173 glVertexAttribPointer(textureLocation_, COMPONENTS, GL_FLOAT, GL_FALSE, 0, 0); | |
174 | |
175 glEnable(GL_BLEND); | |
176 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); | |
177 glDrawArrays(GL_TRIANGLES, 0, data.GetCoordinatesCount() / COMPONENTS); | |
178 glDisable(GL_BLEND); | |
179 | |
180 glDisableVertexAttribArray(positionLocation_); | |
181 glDisableVertexAttribArray(textureLocation_); | |
182 } | |
183 } | |
184 } | |
185 } |