Java 将图像及其遮罩与Android着色器相结合?
我正在为android开发一个应用程序,我使用GL处理一些行为,我遇到了一个具体案例的问题 我有一个环境图像(例如,一个房间),还有一个全白色的遮罩,用黑色标记墙的位置 我想把这两幅图像混合在一起,得到结果(例如,把墙涂成红色) 但首先我需要向着色器指出这两个图像是谁,这里我遇到了麻烦 这是我的片段着色器:Java 将图像及其遮罩与Android着色器相结合?,java,android,opengl-es,shader,Java,Android,Opengl Es,Shader,我正在为android开发一个应用程序,我使用GL处理一些行为,我遇到了一个具体案例的问题 我有一个环境图像(例如,一个房间),还有一个全白色的遮罩,用黑色标记墙的位置 我想把这两幅图像混合在一起,得到结果(例如,把墙涂成红色) 但首先我需要向着色器指出这两个图像是谁,这里我遇到了麻烦 这是我的片段着色器: public static final String fs_Image_mix = "precision mediump float;" +
public static final String fs_Image_mix =
"precision mediump float;" +
"arying LOWP vec4 v_color;" +
"varying vec2 v_texCoord;" +
"uniform sampler2D s_texture;" +
"uniform sampler2D s_mask;" +
"void main() {" +
//" gl_FragColor = texture2D( s_texture, v_texCoord );" +
" vec4 color0 = texture2D(s_texture, v_texCoords);" +
" vec4 color1 = texture2D(s_mask, v_texCoords);" +
" float mask = texture2D(s_mask, v_texCoords).a;" +
" mask = step(1.0, mask);" +
" gl_FragColor = v_color * mix(color0, color1, mask);" +
"}";
这是我通过背景纹理时的绘图功能:
public void Draw(float[] mvpMatrix, int[] textureHandle, int textureIndex){
GLES20.glActiveTexture(GLES20.GL_TEXTURE0);
// Apply transparency to the texture
GLES20.glEnable(GLES20.GL_BLEND);
GLES20.glBlendFunc(GLES20.GL_SRC_ALPHA, GLES20.GL_ONE_MINUS_SRC_ALPHA);
// Ensure that uses the correct texture
GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, textureHandle[textureIndex]);
// get handle to vertex shader's vPosition member
int mPositionHandle = GLES20.glGetAttribLocation(GraphicTools.sp_Image_mix, "vPosition");
// Enable generic vertex attribute array
GLES20.glEnableVertexAttribArray(mPositionHandle);
// Prepare the triangle coordinate data
GLES20.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
// Get handle to texture coordinates location
int mTexCoordLoc = GLES20.glGetAttribLocation(GraphicTools.sp_Image_mix, "a_texCoord" );
// Enable generic vertex attribute array
GLES20.glEnableVertexAttribArray ( mTexCoordLoc );
// Prepare the texturecoordinates
GLES20.glVertexAttribPointer ( mTexCoordLoc, 2, GLES20.GL_FLOAT,
false,
0, uvBuffer);
// Get handle to shape's transformation matrix
int mtrxhandle = GLES20.glGetUniformLocation(GraphicTools.sp_Image_mix, "uMVPMatrix");
// Apply the projection and view transformation
GLES20.glUniformMatrix4fv(mtrxhandle, 1, false, mvpMatrix, 0);
// Get handle to textures locations
int mSamplerLoc = GLES20.glGetUniformLocation (GraphicTools.sp_Image_mix, "s_texture" );
// Set the sampler texture unit to 0, where we have saved the texture.
GLES20.glUniform1i ( mSamplerLoc, 0);
// Draw the triangle
GLES20.glDrawElements(GLES20.GL_TRIANGLES, indices.length,
GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
// Disable vertex array
GLES20.glDisableVertexAttribArray(mPositionHandle);
GLES20.glDisableVertexAttribArray(mTexCoordLoc);
}
如何用所需的掩码填充“s_mask”变量?记住,textureHandle[textureIndex]是背景图像。访问纹理和遮罩纹理
传递给“纹理采样器均匀”的值是纹理所指向的纹理单元的索引
你想过关就一定要过关。要在着色器中使用多个纹理,应执行以下操作:
着色器启动后,将编译着色器阶段并链接着色器程序
可以获得纹理采样器的统一位置
int mTextureSamplerLoc = GLES20.glGetUniformLocation( GraphicTools.sp_Image_mix, "s_texture" );
int mMaskSamplerLoc = GLES20.glGetUniformLocation( GraphicTools.sp_Image_mix, "s_mask" );
在绘制场景之前,必须将纹理绑定到纹理单元
int textureTexUnitIndex = 1;
GLES20.glActiveTexture( GLES20.GL_TEXTURE1 ); // GLES20.GL_TEXTURE1 <--> textureTexUnitIndex
GLES20.glBindTexture( GLES20.GL_TEXTURE_2D, textureHandle[textureIndex] );
int maskTexUnitIndex = 2;
GLES20.glActiveTexture( GLES20.GL_TEXTURE2 ); // GLES20.GL_TEXTURE2 <--> maskTexUnitIndex
GLES20.glBindTexture( GLES20.GL_TEXTURE_2D, ... ) // <-- here you have to add the texture handler of the texture
注意,我使用纹理单元1和2,但您可以使用任何想要的纹理单元。唯一的要求是使用2个不同的纹理单元
int textureTexUnitIndex = 1;
GLES20.glActiveTexture( GLES20.GL_TEXTURE1 ); // GLES20.GL_TEXTURE1 <--> textureTexUnitIndex
GLES20.glBindTexture( GLES20.GL_TEXTURE_2D, textureHandle[textureIndex] );
int maskTexUnitIndex = 2;
GLES20.glActiveTexture( GLES20.GL_TEXTURE2 ); // GLES20.GL_TEXTURE2 <--> maskTexUnitIndex
GLES20.glBindTexture( GLES20.GL_TEXTURE_2D, ... ) // <-- here you have to add the texture handler of the texture
给墙涂上颜色
我有一个环境图像(例如,一个房间),还有一个全白色的遮罩,在墙上的>位置用黑色标记。
我想把这两幅图像混合在一起,得到结果(例如,把墙涂成红色)
我假设您的纹理是RGB纹理,并且遮罩是至少具有一个通道(R)的黑白纹理。
在这些条件下,片段着色器的外观必须如下所示:
precision mediump float;
varying LOWP vec4 v_color;
varying vec2 v_texCoord;
uniform sampler2D s_texture;
uniform sampler2D s_mask;
void main()
{
vec3 texCol = texture2D( s_texture, v_texCoord ).rgb;
float maskCol = texture2D( s_mask, v_texCoord ).r;
vec3 finalCol = s_texture.rgb * mix( v_color.rgb, vec3(1.0), maskCol );
gl_FragColor = vec4( finalCol, 1.0 );
}
这对我很有效,我需要实施更多的行为,但现在我可以进步了,这对我真的很有帮助