如何将更多的每顶点数据发送到kivy中的自定义着色器

时间:2014-09-13 12:26:49

标签: android glsl kivy

我希望能够将更多的每顶点数据传递给我自己的自定义着色器,而不是通常的顶点坐标+纹理坐标。具体来说,我想传递一个值,说明在选择纹理坐标时应该使用哪个动画帧。

我找到了一个例子(http://shadowmint.blogspot.com/2013/10/kivy-textured-quad-easy-right-no.html),并成功地使用Mesh构造函数的参数更改了传递给网格的顶点的格式,如下所示:

Mesh(mode = 'triangles', fmt=[('v_pos', 2, 'float'),  
                              ('v_tex0', 2, 'float'),
                              ('v_frame_i', 1, 'float')]

然后我可以将顶点设置为这样的东西:

vertices = [x-r,y-r, uvpos[0],uvpos[1],animationFrame,
            x-r,y+r, uvpos[0],uvpos[1]+uvsize[1],animationFrame,
            x+r,y-r, uvpos[0]+uvsize[0],uvpos[1],animationFrame,
            x+r,y+r, uvpos[0]+uvsize[0],uvpos[1]+uvsize[1],animationFrame,
            x+r,y-r, uvpos[0]+uvsize[0],uvpos[1],animationFrame,
            x-r,y+r, uvpos[0],uvpos[1]+uvsize[1],animationFrame,
            ]

..当我在Ubuntu中运行时,这很有效,但是当我在我的Android设备上运行时,绘制的纹理要么不绘制,要么看起来顶点或纹理坐标数据是否已损坏/未对齐等等。 / p>

以下是我的着色器代码,以防相关。再一次,当我在ubuntu中运行时,这一切都表现得像我想要的那样,但是当我在Android设备上运行时,它不会。

---VERTEX SHADER---
#ifdef GL_ES
    precision highp float;
#endif

/* vertex attributes */
attribute vec2     v_pos;
attribute vec2     v_tex0;
attribute float    v_frame_i; // for animation

/* uniform variables */
uniform mat4       modelview_mat;
uniform mat4       projection_mat;
uniform vec4       color;
uniform float      opacity;

uniform float      sqrtNumFrames; // the width/height of the sprite-sheet
uniform float      frameWidth;

/* Outputs to the fragment shader */
varying vec4 frag_color;
varying vec2 tc;

void main() {
  frag_color = color * vec4(1.0, 1.0, 1.0, opacity);
  gl_Position = projection_mat * modelview_mat * vec4(v_pos.xy, 0.0, 1.0);

  float f = round(v_frame_i);
  tc = v_tex0;
  float w = (1.0/sqrtNumFrames);
  tc *= w;  
  tc.x += w*mod(f,sqrtNumFrames);        //////////// I think that the problem might
  tc.y += w*round(f / sqrtNumFrames);   ///////////// be related to this code, here?
}

---FRAGMENT SHADER--- 
#ifdef GL_ES
    precision highp float;
#endif

/* Outputs from the vertex shader */
varying vec4 frag_color;
varying vec2 tc;

/* uniform texture samplers */
uniform sampler2D texture0;

uniform vec2 player_pos;
uniform vec2 window_size; // in pixels
void main (void){
  gl_FragColor = frag_color * texture2D(texture0, tc);
}

我想知道它是否与GLSL和int / float数学版本有关(特别是在识别要绘制的sprite表中的哪个图像时,请参阅glsl代码中的注释。一个版本在我的桌面上运行还有另一个在设备上?

非常感谢任何有关实验的建议!

1 个答案:

答案 0 :(得分:1)

在Android设备(Moto X手机)上查看运行版本的日志后,我看到自定义着色器未链接。这似乎是由于使用了函数round(x),我在两种情况下都用floor(x+0.5)替换了,并且着色器现在可以在手机和我的桌面上正常工作。

我认为问题在于手机和我的电脑上支持的GLSL版本不同......但我并不是100%肯定这一点。