Android 如何向kivy中的自定义着色器发送更多逐顶点数据
我希望能够在kivy中向我自己的自定义着色器传递比通常的顶点坐标+纹理坐标更多的逐顶点数据。具体来说,我想传递一个值,该值表示在选择纹理坐标时应使用哪个动画帧 我找到了一个示例(),并使用网格构造函数的参数成功地更改了传递给网格的顶点的格式,如下所示:Android 如何向kivy中的自定义着色器发送更多逐顶点数据,android,glsl,kivy,Android,Glsl,Kivy,我希望能够在kivy中向我自己的自定义着色器传递比通常的顶点坐标+纹理坐标更多的逐顶点数据。具体来说,我想传递一个值,该值表示在选择纹理坐标时应使用哪个动画帧 我找到了一个示例(),并使用网格构造函数的参数成功地更改了传递给网格的顶点的格式,如下所示: Mesh(mode = 'triangles', fmt=[('v_pos', 2, 'float'), ('v_tex0', 2, 'float'),
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,
]
然后,我可以将要绘制的顶点设置为如下所示:
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设备上运行时,绘制的纹理要么不绘制,要么看起来顶点或纹理坐标数据已损坏/未对齐或其他
这是我的着色器代码,以防相关。同样,当我在ubuntu上运行时,这一切都按我所希望的方式运行,但当我在安卓设备上运行时,情况并非如此
---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 math的版本有关(特别是在确定要从精灵表中绘制的图像时,请参阅GLSL代码中的注释。一个版本在我的桌面上运行,另一个版本在设备上运行
如果有任何关于实验的建议,我将不胜感激。在android设备(Moto X手机)上查看运行版本的日志后,我发现自定义着色器没有链接。这似乎是由于使用了函数
round(X)
,我将其替换为floor(X+0.5)
在这两种情况下,着色器现在可以在手机和我的桌面上正常工作
我认为问题在于手机和我的电脑上支持的GLSL版本不同。但我不能100%确定这一点。您能提供一个完整的简单示例来说明这个问题吗?