Vuo  2.3.2
VuoImageResize.c
Go to the documentation of this file.
1 
10 #include "node.h"
11 #include "VuoImageResize.h"
12 
13 #include <OpenGL/CGLMacro.h>
14 
16 #ifdef VUO_COMPILER
18  "title" : "VuoImageResize",
19  "dependencies" : [
20  "VuoImageRenderer"
21  ]
22  });
23 #endif
25 
30  \n#include "VuoGlslAlpha.glsl"
31 
32  varying vec2 fragmentTextureCoordinate;
33  uniform sampler2D texture;
34  uniform vec2 scale;
35  uniform vec2 offset;
36 
37  bool outOfBounds(vec2 coord)
38  {
39  return coord.x < 0 || coord.x > 1 || coord.y < 0 || coord.y > 1;
40  }
41 
42  void main(void)
43  {
44  vec2 uv = (fragmentTextureCoordinate - offset) * scale;
45  gl_FragColor = outOfBounds(uv) ? vec4(0.,0.,0.,0.) : VuoGlsl_sample(texture, uv);
46  }
47 );
48 
53  \n#include "VuoGlslAlpha.glsl"
54 
55  varying vec2 fragmentTextureCoordinate;
56  uniform sampler2DRect texture;
57  uniform vec2 scale;
58  uniform vec2 offset;
59  uniform vec2 textureSize;
60 
61  bool outOfBounds(vec2 coord)
62  {
63  return coord.x < 0 || coord.x > 1 || coord.y < 0 || coord.y > 1;
64  }
65 
66  void main(void)
67  {
68  vec2 uv = (fragmentTextureCoordinate - offset) * scale;
69  gl_FragColor = outOfBounds(uv) ? vec4(0.,0.,0.,0.) : VuoGlsl_sampleRect(texture, uv * textureSize);
70  }
71 );
72 
77 {
78  VuoShader shader;
79  VuoShader shaderRect;
80 };
81 
85 void VuoImageResize_free(void *ir)
86 {
87  struct VuoImageResize_internal *resize = ir;
88  VuoRelease(resize->shader);
89  VuoRelease(resize->shaderRect);
90  free(ir);
91 }
92 
97 {
98  struct VuoImageResize_internal *ir = (struct VuoImageResize_internal *)malloc(sizeof(struct VuoImageResize_internal));
100 
101  ir->shader = VuoShader_make("Resize Image Shader");
102  VuoRetain(ir->shader);
104 
105  ir->shaderRect = VuoShader_make("Resize Image Shader (Rect)");
106  VuoRetain(ir->shaderRect);
108 
109  return ir;
110 }
111 
116 {
117  if (!image)
118  return NULL;
119 
120  if (sizingMode == VuoSizingMode_Proportional)
121  {
122  // Proportionately scale the image, without extra transparent borders.
123  int targetWidth = image->pixelsWide;
124  int targetHeight = image->pixelsHigh;
125  if (image->pixelsWide > width)
126  {
127  targetWidth = width;
128  targetHeight *= (float)width / image->pixelsWide;
129  }
130  if (targetHeight > height)
131  {
132  targetWidth *= (float)height / targetHeight;
133  targetHeight = height;
134  }
135 
136  width = MAX(1, targetWidth);
137  height = MAX(1, targetHeight);
138  }
139 
140  float u = width / (float)(image->pixelsWide);
141  float v = height / (float)(image->pixelsHigh);
142 
143  VuoPoint2d scale = (VuoPoint2d) { 1, 1 };
144  VuoPoint2d offset = (VuoPoint2d) { 0, 0 };
145 
146  switch(sizingMode)
147  {
148  case VuoSizingMode_Fit:
149  if( u < v && u * image->pixelsHigh < height)
150  {
151  scale = (VuoPoint2d) { 1, height/(image->pixelsHigh*u) };
152  offset = (VuoPoint2d) { 0, ((height-(image->pixelsHigh*u))/2)/height };
153  }
154  else
155  {
156  scale = (VuoPoint2d) { width/(image->pixelsWide*v), 1 };
157  offset = (VuoPoint2d) { ((width-(image->pixelsWide*v))/2)/width, 0 };
158  }
159  break;
160 
161  case VuoSizingMode_Fill:
162  if(u > v)
163  {
164  scale = (VuoPoint2d) { 1, height/(image->pixelsHigh*u) };
165  offset = (VuoPoint2d) { 0, ((height-(image->pixelsHigh*u))/2)/height };
166  }
167  else
168  {
169  scale = (VuoPoint2d) { width/(image->pixelsWide*v), 1 };
170  offset = (VuoPoint2d) { ((width-(image->pixelsWide*v))/2)/width, 0 };
171  }
172  break;
173 
174  default:
175  break;
176  }
177 
178  VuoShader shader;
179  struct VuoImageResize_internal *resize = ir;
180  if (image->glTextureTarget == GL_TEXTURE_2D)
181  shader = resize->shader;
182  else if (image->glTextureTarget == GL_TEXTURE_RECTANGLE_ARB)
183  {
184  shader = resize->shaderRect;
185  VuoShader_setUniform_VuoPoint2d(shader, "textureSize", (VuoPoint2d){image->pixelsWide, image->pixelsHigh});
186  }
187  else
188  {
189  VUserLog("Error: Unknown texture target %s.", VuoGl_stringForConstant(image->glTextureTarget));
190  return NULL;
191  }
192 
193  VuoShader_setUniform_VuoImage ( shader, "texture", image );
194  VuoShader_setUniform_VuoPoint2d( shader, "scale", scale );
195  VuoShader_setUniform_VuoPoint2d( shader, "offset", offset );
196 
197  VuoShader_setTransparent(shader, sizingMode == VuoSizingMode_Fit);
198 
199  return VuoImageRenderer_render(shader, width, height, VuoImage_getColorDepth(image));
200 }