@@ -17,19 +17,11 @@ layout(location = 2) in vec2 tex_coord;
1717
1818out vec2 fragment_tex_coord;
1919
20- uniform ivec2 flip ;
20+ uniform mat4 vertex_transformation ;
2121
2222void main() {
23- gl_Position = vec4(position, 0.0, 1.0);
23+ gl_Position = vec4(position, 0.0, 1.0) * vertex_transformation ;
2424 fragment_tex_coord = tex_coord;
25- if (flip.x > 0)
26- {
27- fragment_tex_coord.s = 1.0 - fragment_tex_coord.s;
28- }
29- if (flip.y > 0)
30- {
31- fragment_tex_coord.t = 1.0 - fragment_tex_coord.t;
32- }
3325}
3426)" ;
3527
@@ -53,13 +45,6 @@ CopyTexture::CopyTexture()
5345{
5446 m_framebuffer.CreateColorAttachment (0 , 0 );
5547
56- std::string vertexShader (ShaderVersion);
57- std::string fragmentShader (ShaderVersion);
58- vertexShader.append (CopyTextureVertexShader);
59- fragmentShader.append (CopyTextureFragmentShader);
60-
61- m_shader.CompileProgram (vertexShader, fragmentShader);
62-
6348 m_mesh.SetRenderPrimitiveType (Mesh::PrimitiveType::TriangleStrip);
6449
6550 m_mesh.SetVertexCount (4 );
@@ -78,7 +63,9 @@ CopyTexture::CopyTexture()
7863 m_mesh.Update ();
7964}
8065
81- void CopyTexture::Draw (const std::shared_ptr<class Texture >& originalTexture, bool flipVertical, bool flipHorizontal)
66+ void CopyTexture::Draw (ShaderCache& shaderCache,
67+ const std::shared_ptr<class Texture >& originalTexture,
68+ bool flipVertical, bool flipHorizontal)
8269{
8370 if (originalTexture == nullptr )
8471 {
@@ -87,10 +74,12 @@ void CopyTexture::Draw(const std::shared_ptr<class Texture>& originalTexture, bo
8774
8875 // Just bind the texture and draw it to the currently bound buffer.
8976 originalTexture->Bind (0 );
90- Copy (flipVertical, flipHorizontal);
77+ Copy (shaderCache, flipVertical, flipHorizontal);
9178}
9279
93- void CopyTexture::Draw (const std::shared_ptr<class Texture >& originalTexture, const std::shared_ptr<class Texture >& targetTexture,
80+ void CopyTexture::Draw (ShaderCache& shaderCache,
81+ const std::shared_ptr<class Texture >& originalTexture,
82+ const std::shared_ptr<class Texture >& targetTexture,
9483 bool flipVertical, bool flipHorizontal)
9584{
9685 if (originalTexture == nullptr ||
@@ -128,7 +117,7 @@ void CopyTexture::Draw(const std::shared_ptr<class Texture>& originalTexture, co
128117 m_framebuffer.GetAttachment (0 , TextureAttachment::AttachmentType::Color, 0 )->Texture (targetTexture);
129118 }
130119
131- Copy (flipVertical, flipHorizontal);
120+ Copy (shaderCache, flipVertical, flipHorizontal);
132121
133122 // Rebind our internal texture.
134123 if (targetTexture)
@@ -139,7 +128,9 @@ void CopyTexture::Draw(const std::shared_ptr<class Texture>& originalTexture, co
139128 Framebuffer::Unbind ();
140129}
141130
142- void CopyTexture::Draw (const std::shared_ptr<class Texture >& originalTexture, Framebuffer& framebuffer, int framebufferIndex,
131+ void CopyTexture::Draw (ShaderCache& shaderCache,
132+ const std::shared_ptr<class Texture >& originalTexture,
133+ Framebuffer& framebuffer, int framebufferIndex,
143134 bool flipVertical, bool flipHorizontal)
144135{
145136 if (originalTexture == nullptr //
@@ -162,7 +153,7 @@ void CopyTexture::Draw(const std::shared_ptr<class Texture>& originalTexture, Fr
162153 // Draw from unflipped texture
163154 originalTexture->Bind (0 );
164155
165- Copy (flipVertical, flipHorizontal);
156+ Copy (shaderCache, flipVertical, flipHorizontal);
166157
167158 // Swap texture attachments
168159 auto tempAttachment = framebuffer.GetAttachment (framebufferIndex, TextureAttachment::AttachmentType::Color, 0 );
@@ -174,6 +165,74 @@ void CopyTexture::Draw(const std::shared_ptr<class Texture>& originalTexture, Fr
174165 Framebuffer::Unbind ();
175166}
176167
168+ void CopyTexture::Draw (ShaderCache& shaderCache,
169+ const std::shared_ptr<struct Texture >& originalTexture,
170+ const std::shared_ptr<struct Texture >& targetTexture,
171+ int left, int top, int width, int height)
172+ {
173+ if (originalTexture == nullptr ||
174+ originalTexture->Empty () ||
175+ targetTexture == nullptr ||
176+ targetTexture->Empty () ||
177+ originalTexture == targetTexture)
178+ {
179+ return ;
180+ }
181+
182+ UpdateTextureSize (targetTexture->Width (), targetTexture->Height ());
183+
184+ if (m_width == 0 || m_height == 0 )
185+ {
186+ return ;
187+ }
188+
189+ std::shared_ptr<class Texture > internalTexture;
190+
191+ m_framebuffer.Bind (0 );
192+
193+ // Draw from original texture
194+ originalTexture->Bind (0 );
195+ internalTexture = m_framebuffer.GetColorAttachmentTexture (0 , 0 );
196+ m_framebuffer.GetAttachment (0 , TextureAttachment::AttachmentType::Color, 0 )->Texture (targetTexture);
197+
198+ Copy (shaderCache, left, top, width, height);
199+
200+ // Rebind our internal texture.
201+ m_framebuffer.GetAttachment (0 , TextureAttachment::AttachmentType::Color, 0 )->Texture (internalTexture);
202+
203+ Framebuffer::Unbind ();
204+ }
205+
206+ void CopyTexture::Draw (ShaderCache& shaderCache,
207+ GLuint originalTexture,
208+ int viewportWidth, int viewportHeight,
209+ int left, int top, int width, int height)
210+ {
211+ if (originalTexture == 0 )
212+ {
213+ return ;
214+ }
215+
216+ if (viewportWidth == 0 || viewportHeight == 0 )
217+ {
218+ return ;
219+ }
220+
221+ int oldWidth = m_width;
222+ int oldHeight = m_height;
223+
224+ m_width = viewportWidth;
225+ m_height = viewportHeight;
226+
227+ // Draw from original texture
228+ glActiveTexture (GL_TEXTURE0);
229+ glBindTexture (GL_TEXTURE_2D, originalTexture);
230+ Copy (shaderCache, left, top, width, height);
231+
232+ m_width = oldWidth;
233+ m_height = oldHeight;
234+ }
235+
177236auto CopyTexture::Texture () -> std::shared_ptr<class Texture>
178237{
179238 return m_framebuffer.GetColorAttachmentTexture (0 , 0 );
@@ -193,11 +252,18 @@ void CopyTexture::UpdateTextureSize(int width, int height)
193252 m_framebuffer.SetSize (m_width, m_height);
194253}
195254
196- void CopyTexture::Copy (bool flipVertical, bool flipHorizontal)
255+ void CopyTexture::Copy (ShaderCache& shaderCache,
256+ bool flipVertical, bool flipHorizontal)
197257{
198- m_shader.Bind ();
199- m_shader.SetUniformInt (" texture_sampler" , 0 );
200- m_shader.SetUniformInt2 (" flip" , {flipHorizontal ? 1 : 0 , flipVertical ? 1 : 0 });
258+ glm::mat4x4 flipMatrix (1.0 );
259+
260+ flipMatrix[0 ][0 ] = flipHorizontal ? -1.0 : 1.0 ;
261+ flipMatrix[1 ][1 ] = flipVertical ? -1.0 : 1.0 ;
262+
263+ std::shared_ptr<Shader> shader = BindShader (shaderCache);
264+
265+ shader->SetUniformInt (" texture_sampler" , 0 );
266+ shader->SetUniformMat4x4 (" vertex_transformation" , flipMatrix);
201267
202268 m_sampler.Bind (0 );
203269
@@ -209,5 +275,57 @@ void CopyTexture::Copy(bool flipVertical, bool flipHorizontal)
209275 Shader::Unbind ();
210276}
211277
278+ void CopyTexture::Copy (ShaderCache& shaderCache,
279+ int left, int top, int width, int height)
280+ {
281+ glm::mat4x4 translationMatrix (1.0 );
282+ translationMatrix[0 ][0 ] = static_cast <float >(width) / static_cast <float >(m_width);
283+ translationMatrix[1 ][1 ] = static_cast <float >(height) / static_cast <float >(m_height);
284+
285+ translationMatrix[3 ][0 ] = static_cast <float >(left) / static_cast <float >(m_width);
286+ translationMatrix[3 ][1 ] = static_cast <float >(top) / static_cast <float >(m_height);
287+
288+ std::shared_ptr<Shader> shader = BindShader (shaderCache);
289+
290+ shader->SetUniformInt (" texture_sampler" , 0 );
291+ shader->SetUniformMat4x4 (" vertex_transformation" , translationMatrix);
292+
293+ m_sampler.Bind (0 );
294+
295+ m_mesh.Draw ();
296+
297+ Mesh::Unbind ();
298+ Sampler::Unbind (0 );
299+ Shader::Unbind ();
300+ }
301+
302+ std::shared_ptr<Shader> CopyTexture::BindShader (ShaderCache& shaderCache)
303+ {
304+ auto shader = m_shader.lock ();
305+
306+ if (!shader)
307+ {
308+ shader = shaderCache.Get (" copy_texture" );
309+ }
310+
311+ if (!shader)
312+ {
313+ std::string vertexShader (ShaderVersion);
314+ std::string fragmentShader (ShaderVersion);
315+ vertexShader.append (CopyTextureVertexShader);
316+ fragmentShader.append (CopyTextureFragmentShader);
317+
318+ shader = std::make_shared<Shader>();
319+ shader->CompileProgram (vertexShader, fragmentShader);
320+
321+ m_shader = shader;
322+ shaderCache.Insert (" copy_texture" , shader);
323+ }
324+
325+ shader->Bind ();
326+
327+ return shader;
328+ }
329+
212330} // namespace Renderer
213331} // namespace libprojectM
0 commit comments