处理,使用音频波形内部的纹理

Processing, using texture inside the audio waveform

我一直在尝试使纹理( img )仅在波形活动的地方可见。但到目前为止,我的尝试都失败了。不太明白vertex的用法

PImage img;
import ddf.minim.*;

Minim minim;
AudioPlayer song;

void setup()
{
  size(800, 600,P2D);
  minim = new Minim(this);
  song = minim.loadFile("song.mp3");
  song.play();
  img = loadImage("img.jpg");
}

void draw()
{
  background(0);
  stroke(255);
  for (int i = 0; i < song.bufferSize() - 1; i++)
  {
    beginShape();
    texture(img);
    vertex(0,height/2);
    vertex(i, height-100 - song.right.get(i)*50);
    vertex(i+1, height-100 - song.right.get(i+1)*50);
    vertex(width,height/2);
    vertex(0,height/2);
    vertex(0,height/2+100); 
    endShape();
  }
} 

你快完成了:

  • 您正在传递渲染形状的顶点位置的 x、y 值
  • 您没有传递纹理映射 u,v 坐标

请务必阅读 vertex() 参考资料:

This function is also used to map a texture onto geometry. The texture() function declares the texture to apply to the geometry and the u and v coordinates set define the mapping of this texture to the form. By default, the coordinates used for u and v are specified in relation to the image's size in pixels, but this relation can be changed with textureMode().

不清楚您要绘制什么形状,但您可以做的一件简单的事情就是将 x、y 坐标也作为 u、v 坐标传递(而不仅仅是 vertex(x,y); 使用 vertex(x,y,u,v);):

PImage img;
import ddf.minim.*;

Minim minim;
AudioPlayer song;

void setup()
{
  size(800, 600,P2D);
  noStroke();
  minim = new Minim(this);
  song = minim.loadFile("song.mp3");
  song.play();
  img = loadImage("img.jpg");
}

void draw()
{
  background(0);
  stroke(255);
  for (int i = 0; i < song.bufferSize() - 1; i++)
  {
    beginShape();
    texture(img);
    vertex(0,height/2,                                        //vertex 0,x,y
           0,height/2);                                       //vertex 0,u,v
    vertex(i, height-100 - song.right.get(i)*50,              //vertex 1,x,y
           i, height-100 - song.right.get(i)*50);             //vertex 1,u,v
    vertex(i+1, height-100 - song.right.get(i+1)*50,          //vertex 2,x,y
           i+1, height-100 - song.right.get(i+1)*50);         //vertex 2,u,v
    vertex(width,height/2,                                    //vertex 3,x,y
           width,height/2);                                   //vertex 3,u,v
    vertex(0,height/2,                                        //vertex 4,x,y
           0,height/2);                                       //vertex 4,u,v
    vertex(0,height/2+100,                                    //vertex 5,x,y
           0,height/2+100);                                   //vertex 5,u,v
    endShape();
  }
} 

未测试,但评论应该有助于发现差异。

这是一个使用 vertex() 和 texture() 的超级基本示例:

PImage img;
void setup(){
  size(100,100,P2D);
  //make a texture
  img = createImage(50,50,RGB);
  for(int i = 0 ; i < img.pixels.length; i++) {
    int x = i % img.width;
    int y = i / img.height;
    if(x % 4 == 0 && y % 4 == 0){
      img.pixels[i] = color(255);
    }else{
      img.pixels[i] = color(0);
    }
  }
  img.updatePixels();
}
void draw(){
  background(0);
  //sampling different u,v coordinates (vertex 1 is mapped to mouse) for same x,y
  beginShape();
  texture(img);
  vertex(0,0,0,0);
  vertex(50,0,mouseX,mouseY);
  vertex(50,50,50,50);
  vertex(0,50,0,50);
  endShape();

  text("u:"+mouseX+"v:"+mouseY,5,height);

  translate(50,0);
  //mapping u,v to x,y coordinates
  beginShape();
  texture(img);
  vertex(0,0,0,0);
  vertex(50,0,50,0);
  vertex(50,50,50,50);
  vertex(0,50,0,50);
  endShape();

}

注意当您移动鼠标时纹理如何扭曲,因为它控制着顶点 1 的纹理坐标。 vertex(x,y,u,v) 与 vertex(x,y) 非常相似,但除了顶点在屏幕上渲染的坐标外,您还可以控制纹理采样的坐标。

如参考文献所述,默认情况下 textureMode() 是图像,这意味着 u、v 坐标在图像坐标中(从 0,0 到纹理图像宽度、高度)。还有另一种模式可用:NORMAL in which the u,v sampling coordinates are normalised (between 0.0 and 1.0) is closer to what you might have spotted in 3D applications UV mapping features