通过SurfaceTexture在GLSurfaceView上显示相机流

时间:2012-11-02 17:57:38

标签: android opengl-es android-camera

我正在尝试通过传递给OpenGL ES 2.0着色器的SurfaceTexture在GLSurfaceView中显示相机流。

我从这个post中获取灵感。

图像已完整但未在我的平板电脑上正确显示。 屏幕分为2x2部分。图像显示在左上角,而其他三个部分显示为黑色。

我怀疑问题来自于我对记录的序列返回的转换矩阵的使用here

updateTexImage();
getTransformMatrix(...);

我在顶点着色器中传输此矩阵,以生成片段着色器的纹理坐标。

顶点着色器:

attribute vec3 aPosition;
uniform mat4 uMvpTransform;
// Matrix retrieved by getTransformMatrix(...);
uniform mat4 uTexMatTransform;
varying vec2 vTexCoord;

void main(void)
{
  gl_Position = uMvpTransform *vec4(aPosition.xyz, 1);
  vec4 l_tex =  uTexMatTransform*vec4(aPosition.xyz, 1);
  vTexCoord=l_tex.xy;
}

片段着色器:

#extension GL_OES_EGL_image_external : require
varying mediump vec2 vTexCoord;
uniform samplerExternalOES uSampler; 

void main(void) 
{ 
    mediump vec4 l_tex = texture2D(uSampler, vTexCoord);
    gl_FragColor=l_tex;
}

纹理附加到以下方块:

 // Image container
 GLfloat l_vertices[] = {
  -1.0f, 1.0f,  0.0f,
  -1.0f, -1.0f,  0.0f,
  1.0f,  -1.0f,  0.0f,
  1.0f,  1.0f,  0.0f };

有没有人有类似的东西?

2012年11月3日编辑:

顶点着色器的校正:

attribute vec3 aPosition;
attribute vec2 aTexCoord;
uniform mat4 uMvpTransform;
// Matrix retrieved by getTransformMatrix(...);
uniform mat4 uTexMatTransform;
varying vec2 vTexCoord;

void main(void)
{
  gl_Position = uMvpTransform *vec4(aPosition.xyz, 1);
  vec4 l_tex =  uTexMatTransform*vec4(aTexCoord.xy,0, 1);
  vTexCoord=l_tex.xy;
}

使用:

// Texture
GLfloat l_texCoord[] = {
   0.0f, 1.0f,
   0.0f, 0.0f,
   1.0f,  0.0f,
   1.0f,  1.0f

};

2 个答案:

答案 0 :(得分:4)

我已成功使用SurfaceTexture在自定义opengl纹理上绘制相框,而不使用android提供的转换矩阵。

尝试以正常纹理绘制的方式定义索引顶点和纹理。比如这样。

const GLfloat Vertices[] = {0.5, -0.5, 0,
                            0.5, 0.5, 0,
                           -0.5, 0.5, 0,
                           -0.5, -0.5, 0};

const GLubyte Indices[] = { 0, 1, 2,
                            2, 3, 0 };

const GLfloat Textures[] = { 1.,0.,
                             0.,0.,
                             0.,1.,
                             1.,1. };

您应该能够像使用普通纹理一样使用surfacetexture。

如果您想要执行某种3D投影,这是关于如何生成适当的MVP矩阵的good post。您可以使用它与顶点着色器中的位置相乘。

答案 1 :(得分:3)

由于我遇到了同样的问题,即使问题有点陈旧,也可能值得详细说明“为什么要使用转换矩阵”

转换矩阵映射SurfaceTexture使用的特定坐标集(或更可能, 由当前视频源 流式传输到SurfaceTexture ... )到标准的OpenGL纹理坐标。

应该明确使用的原因是,尽管Startibartfast的答案适用于一个或多个特定的设置,并且可能很容易实现,但是当运行相同的程序时,它可能会产生奇怪的可视化错误不同的设备,具体取决于每个平台的视频驱动程序实现。

在我的情况下,例如,变换矩阵只是翻转内容(我将SurfaceTexture与Nexus 7上的MediaPlayer结合使用)而不是Fabien R指出的结果。

使用矩阵的正确方法在2012年11月3日的 Fabien R编辑中指出,我报告了一些小的装饰(如使用st索引)和一个小的修正int / float不匹配:

attribute   vec2 uv;
varying     vec2 vTexCoord;
uniform     mat4 transformMatrix;

vTexCoord = (transformMatrix * vec4(uv, 0.0, 1.0)).st;

希望有所帮助