2012-08-26 36 views
8

द्वारा आरजीबी रूपांतरण के लिए वाईयूवी मुझे वाईयूवी प्रारूप से आरजीबी तक एंड्रॉइड में कैमरा पूर्वावलोकन के रूप में परिवर्तित करने में समस्या है। रूपांतरण का उद्देश्य कुछ प्रभाव लागू करना है। मैं खंड शेडर द्वारा रूपांतरित करने की कोशिश करता हूं क्योंकि देशी कोड द्वारा कनवर्टन धीमा है (लगभग 14 एफपीएस)। संदर्भ जो मैंने उपयोग किया है http://jyrom.tistory.com/m/post/view/id/187 है। मैं एंड्रॉइड मंच पर इस कोड को पोर्ट करने का प्रयास करता हूं, लेकिन परिणाम काले-हरे आयताकार है। लेकिन, मैं आउटपुट के माध्यम से कुछ रूप देख सकता हूं जो मुझे मिलता है। क्या आप कृपया इस मुद्दे को हल करने में मेरी सहायता करने की कोशिश कर सकते हैं। मेरा मानना ​​है कि यह लोकप्रिय समस्या है: कैमरा पूर्वावलोकन पर प्रभाव लागू करें। मैं परीक्षण के लिए अपने प्रोजेक्ट को एक लिंक भी देता हूं: https://dl.dropbox.com/u/12829395/application/FilterGL/FilterGL.zip। धन्यवाद।
UPDATED:
यह मेरा onPreviewFrame विधि: खंडन शेडर

public void onPreviewFrame(byte[] data, Camera camera) { 
    yBuffer.put(data); 
    yBuffer.position(0); 

    System.arraycopy(data, U_INDEX, uData, 0, LENGTH_4 * 2); 
    uBuffer.put(uData); 
    uBuffer.position(0); 

    System.arraycopy(data, V_INDEX, vData, 0, LENGTH_4); 
    vBuffer.put(vData); 
    vBuffer.position(0); 
} 

इस तरह मैं onDrawFrame विधि में ओपन बनावट के लिए बाइट सरणियों बाँध:

GLES20.glUniform1i(yTexture, 1); 
    GLES20.glTexImage2D( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, 
      320, 240, 0, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, yBuffer); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 

    GLES20.glUniform1i(uTexture, 2); 
    GLES20.glTexImage2D( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, 
      160, 120, 0, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, uBuffer); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 

    GLES20.glUniform1i(vTexture, 3); 
    GLES20.glTexImage2D( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, 
      160, 120, 0, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, vBuffer); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 

और यह मेरा टुकड़ा शेडर कोड है:

#ifdef GL_ES 
precision highp float; 
#endif 

varying vec2 v_texCoord; 
uniform sampler2D y_texture; 
uniform sampler2D u_texture; 
uniform sampler2D v_texture; 

void main() 
{ 
    float nx,ny,r,g,b,y,u,v; 
    nx=v_texCoord.x; 
    ny=v_texCoord.y; 
    y=texture2D(y_texture,v_texCoord).r; 
    u=texture2D(u_texture,v_texCoord).r; 
    v=texture2D(v_texture,v_texCoord).r; 

    y=1.1643*(y-0.0625); 
    u=u-0.5; 
    v=v-0.5; 

    r=y+1.5958*v; 
    g=y-0.39173*u-0.81290*v; 
    b=y+2.017*u; 

    gl_FragColor = vec4(r,g,b,1.0); 
} 

उत्तर

3

सुनिश्चित नहीं हैं कि अगर आप पहले से ही इस problem.My जवाब

  1. तय कर दी है डिफ़ॉल्ट कैमरा उत्पादन करके NV12 है, लेकिन टुकड़ा शेडर YUV में आप YV12 उपयोग कर रहे हैं आरजीबी के लिए -> आरजीबी। आप सुनिश्चित करें कि आप किसी भी glTexImage2D को कॉल करने से पहले

    GLES20.glActiveTexture(GLES20.GL_TEXTURE2); GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, muTextureName)

    करते हैं setPreviewFormat(ImageFormat.YV12); करना होगा, या कुछ अन्य शेडर

  2. का उपयोग 3 बनावट रहे हैं हो सकता है। और glTexSubImage2D

  3. आप प्रत्येक फ्रेम और glTexImage2D के साथ एक बार glTexSubImage2D का भी उपयोग कर सकते हैं। यू और वी के

  4. आकार YV12 के लिए ही है, कम से कम,

    System.arraycopy(data, U_INDEX, uData, 0, LENGTH_4 * 2);

    System.arraycopy(data, U_INDEX, uData, 0, LENGTH_4); परिवर्तन कोड में आकार के हिसाब से होना चाहिए।

1

अंततः आपके प्रोजेक्ट डिस्प्ले कैमरा पूर्वावलोकन बनाये। मुझे 2 समस्याएं मिलीं: 1. बाध्यकारी और सतह की विशेषताओं को बदलने से पहले आपको GLES20.glActiveTexture (GLES20.surfacenumber) को कॉल करना होगा; 2. अधिक महत्वपूर्ण और छिपी समस्या यह है कि GLES20.glTexImage2D() चौड़ाई और ऊंचाई के साथ काम नहीं करता है, जो 2 संख्याओं की शक्ति नहीं है। आकार के साथ बनावट लोड करने के बाद, उदाहरण के लिए, 1024X1024, आपको GLES20.glTexSubImage2D()

शुभकामनाएं कॉल करनी चाहिए!

2

मुझे नहीं पता कि आपने अपनी समस्या का समाधान किया है या नहीं।

मैंने आपके कोड का उपयोग किया और मैंने इस मोड में हल किया।

public class MyRenderer implements Renderer{ 
public static final int recWidth = Costanti.recWidth; 
public static final int recHeight = Costanti.recHeight; 

private static final int U_INDEX = recWidth*recHeight; 
private static final int V_INDEX = recWidth*recHeight*5/4; 
private static final int LENGTH = recWidth*recHeight; 
private static final int LENGTH_4 = recWidth*recHeight/4; 

private int previewFrameWidth = 256; 
private int previewFrameHeight = 256; 

private int[] yTextureNames; 
private int[] uTextureNames; 
private int[] vTextureNames; 

private MainActivity activity; 

private FloatBuffer mVertices; 
private ShortBuffer mIndices; 

private int mProgramObject; 
private int mPositionLoc; 
private int mTexCoordLoc; 

private int yTexture; 
private int uTexture; 
private int vTexture; 

private final float[] mVerticesData = { -1.f, 1.f, 0.0f, // Position 0 
     0.0f, 0.0f, // TexCoord 0 
     -1.f, -1.f, 0.0f, // Position 1 
     0.0f, 1.0f, // TexCoord 1 
     1.f, -1.f, 0.0f, // Position 2 
     1.0f, 1.0f, // TexCoord 2 
     1.f, 1.f, 0.0f, // Position 3 
     1.0f, 0.0f // TexCoord 3 
}; 
private final short[] mIndicesData = { 0, 1, 2, 0, 2, 3 }; 

private ByteBuffer yBuffer; 
private ByteBuffer uBuffer; 
private ByteBuffer vBuffer; 

private IntBuffer frameBuffer; 
private IntBuffer renderBuffer; 
private IntBuffer parameterBufferWidth; 
private IntBuffer parameterBufferHeigth; 

byte[] ydata = new byte[LENGTH]; 
byte[] uData = new byte[LENGTH_4]; 
byte[] vData = new byte[LENGTH_4]; 

public MyRenderer(MainActivity activity) { 
    this.activity = activity; 

    mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4) 
      .order(ByteOrder.nativeOrder()).asFloatBuffer(); 
    mVertices.put(mVerticesData).position(0); 

    mIndices = ByteBuffer.allocateDirect(mIndicesData.length * 2) 
      .order(ByteOrder.nativeOrder()).asShortBuffer(); 
    mIndices.put(mIndicesData).position(0); 

    yBuffer = MyGraphUtils.makeByteBuffer(LENGTH); 
    uBuffer = MyGraphUtils.makeByteBuffer(LENGTH_4/* * 2*/); 
    vBuffer = MyGraphUtils.makeByteBuffer(LENGTH_4); 
} 

@Override 
public void onSurfaceChanged(GL10 gl, int width, int height) { 
    GLES20.glActiveTexture(GLES20.GL_ACTIVE_TEXTURE); 
    GLES20.glViewport(0, 0, width, height); 
} 

@Override 
public void onSurfaceCreated(GL10 gl, EGLConfig config) { 
    Log.d("debug", "on surface created"); 
    // Define a simple shader program for our point. 
    final String vShaderStr = readTextFileFromRawResource(activity, R.raw.v_simple); 
    final String fShaderStr = readTextFileFromRawResource(activity, R.raw.f_convert); 
    frameBuffer = IntBuffer.allocate(1); 
    renderBuffer= IntBuffer.allocate(1); 

    GLES20.glEnable(GLES20.GL_TEXTURE_2D); 

    GLES20.glGenFramebuffers(1, frameBuffer); 
    GLES20.glGenRenderbuffers(1, renderBuffer); 
    GLES20.glActiveTexture(GLES20.GL_ACTIVE_TEXTURE); 
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, frameBuffer.get(0)); 
    GLES20.glClear(0); 
    GLES20.glBindRenderbuffer(GLES20.GL_RENDERBUFFER, renderBuffer.get(0));  

    GLES20.glRenderbufferStorage(GLES20.GL_RENDERBUFFER, GLES20.GL_DEPTH_COMPONENT16, 
           320, 240); 

    parameterBufferHeigth = IntBuffer.allocate(1); 
    parameterBufferWidth = IntBuffer.allocate(1); 
    GLES20.glGetRenderbufferParameteriv(GLES20.GL_RENDERBUFFER, GLES20.GL_RENDERBUFFER_WIDTH, parameterBufferWidth); 
    GLES20.glGetRenderbufferParameteriv(GLES20.GL_RENDERBUFFER, GLES20.GL_RENDERBUFFER_HEIGHT, parameterBufferHeigth); 
    GLES20.glFramebufferRenderbuffer(GLES20.GL_FRAMEBUFFER, GLES20.GL_COLOR_ATTACHMENT0, GLES20.GL_RENDERBUFFER, renderBuffer.get(0)); 
    if (GLES20.glCheckFramebufferStatus(GLES20.GL_FRAMEBUFFER)!=GLES20.GL_FRAMEBUFFER_COMPLETE){ 
     Log.d("debug", "gl frame buffer status != frame buffer complete"); 
    } 
    GLES20.glBindFramebuffer(GLES20.GL_FRAMEBUFFER, 0); 
    GLES20.glClear(0); 

    mProgramObject = loadProgram(vShaderStr, fShaderStr); 

    // Get the attribute locations 
    mPositionLoc = GLES20.glGetAttribLocation(mProgramObject, "a_position"); 
    mTexCoordLoc = GLES20.glGetAttribLocation(mProgramObject, "a_texCoord"); 

    GLES20.glEnable(GLES20.GL_TEXTURE_2D); 
    yTexture = GLES20.glGetUniformLocation(mProgramObject, "y_texture"); 
    yTextureNames = new int[1]; 
    GLES20.glGenTextures(1, yTextureNames, 0); 
    int yTextureName = yTextureNames[0]; 

    GLES20.glEnable(GLES20.GL_TEXTURE_2D); 
    uTexture = GLES20.glGetUniformLocation(mProgramObject, "u_texture"); 
    uTextureNames = new int[1]; 
    GLES20.glGenTextures(1, uTextureNames, 0); 
    int uTextureName = uTextureNames[0]; 

    GLES20.glEnable(GLES20.GL_TEXTURE_2D); 
    vTexture = GLES20.glGetUniformLocation(mProgramObject, "v_texture"); 
    vTextureNames = new int[1]; 
    GLES20.glGenTextures(1, vTextureNames, 0); 
    int vTextureName = vTextureNames[0]; 

    GLES20.glClearColor(1.0f, 0.0f, 0.0f, 0.0f); 
} 

@Override 
public final void onDrawFrame(GL10 gl) { 
    Log.d("debug", "on Draw frame"); 
    // Clear the color buffer 
    GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); 

    // Use the program object 
    GLES20.glUseProgram(mProgramObject); 

    // Load the vertex position 
    mVertices.position(0); 
    GLES20.glVertexAttribPointer(mPositionLoc, 3, GLES20.GL_FLOAT, false, 5*4, mVertices); 
    // Load the texture coordinate 
    mVertices.position(3); 
    GLES20.glVertexAttribPointer(mTexCoordLoc, 2, GLES20.GL_FLOAT, false, 5*4, mVertices); 

    GLES20.glEnableVertexAttribArray(mPositionLoc); 
    GLES20.glEnableVertexAttribArray(mTexCoordLoc); 

    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, yTextureNames[0]); 
    GLES20.glTexImage2D( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, 
      320, 240, 0, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, yBuffer); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 
    GLES20.glActiveTexture(GLES20.GL_TEXTURE1); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, yTextureNames[0]); 
    GLES20.glUniform1i(yTexture, 0); 

    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, uTextureNames[0]); 
    GLES20.glTexImage2D( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, 
      160, 120, 0, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, uBuffer); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 
    GLES20.glActiveTexture(GLES20.GL_TEXTURE1+2); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, uTextureNames[0]); 
    GLES20.glUniform1i(uTexture, 2); 

    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, vTextureNames[0]); 
    GLES20.glTexImage2D( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, 
      160, 120, 0, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, vBuffer); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 
    GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 
    GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 
    GLES20.glActiveTexture(GLES20.GL_TEXTURE1+1); 
    GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, vTextureNames[0]); 
    GLES20.glUniform1i(vTexture, 1); 

    GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, mIndices); 
} 



public void setPreviewFrameSize(int realWidth, int realHeight) { 
    previewFrameHeight = realHeight; 
    previewFrameWidth = realWidth; 
} 

public static String readTextFileFromRawResource(final Context context, final int resourceId) { 
    final InputStream inputStream = context.getResources().openRawResource(resourceId); 
    final InputStreamReader inputStreamReader = new InputStreamReader(inputStream); 
    final BufferedReader bufferedReader = new BufferedReader(inputStreamReader); 

    String nextLine; 
    final StringBuilder body = new StringBuilder(); 

    try { 
     while ((nextLine = bufferedReader.readLine()) != null) { 
      body.append(nextLine); 
      body.append('\n'); 
     } 
    } catch (IOException e) { 
     return null; 
    } 

    return body.toString(); 
} 

public static int loadShader(int type, String shaderSrc) { 
    int shader; 
    int[] compiled = new int[1]; 

    // Create the shader object 
    shader = GLES20.glCreateShader(type); 
    if (shader == 0) { 
     return 0; 
    } 
    // Load the shader source 
    GLES20.glShaderSource(shader, shaderSrc); 
    // Compile the shader 
    GLES20.glCompileShader(shader); 
    // Check the compile status 
    GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0); 

    if (compiled[0] == 0) { 
     Log.e("ESShader", GLES20.glGetShaderInfoLog(shader)); 
     GLES20.glDeleteShader(shader); 
     return 0; 
    } 
    return shader; 
} 

public static int loadProgram(String vertShaderSrc, String fragShaderSrc) { 
    int vertexShader; 
    int fragmentShader; 
    int programObject; 
    int[] linked = new int[1]; 

    // Load the vertex/fragment shaders 
    vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertShaderSrc); 
    if (vertexShader == 0) { 
     return 0; 
    } 

    fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragShaderSrc); 
    if (fragmentShader == 0) { 
     GLES20.glDeleteShader(vertexShader); 
     return 0; 
    } 

    // Create the program object 
    programObject = GLES20.glCreateProgram(); 

    if (programObject == 0) { 
     return 0; 
    } 

    GLES20.glAttachShader(programObject, vertexShader); 
    GLES20.glAttachShader(programObject, fragmentShader); 

    // Link the program 
    GLES20.glLinkProgram(programObject); 

    // Check the link status 
    GLES20.glGetProgramiv(programObject, GLES20.GL_LINK_STATUS, linked, 0); 

    if (linked[0] == 0) { 
     Log.e("ESShader", "Error linking program:"); 
     Log.e("ESShader", GLES20.glGetProgramInfoLog(programObject)); 
     GLES20.glDeleteProgram(programObject); 
     return 0; 
    } 

    // Free up no longer needed shader resources 
    GLES20.glDeleteShader(vertexShader); 
    GLES20.glDeleteShader(fragmentShader); 

    return programObject; 
} 

@Override 
public void onPreviewFrame(byte[] data, Camera camera) { 

    System.arraycopy(data, 0, ydata, 0, LENGTH); 
    yBuffer.put(ydata); 
    yBuffer.position(0); 

    System.arraycopy(data, U_INDEX, uData, 0, LENGTH_4); 
    uBuffer.put(uData); 
    uBuffer.position(0); 

    System.arraycopy(data, V_INDEX, vData, 0, LENGTH_4); 
    vBuffer.put(vData); 
    vBuffer.position(0); 
} 

}

1

सबसे तेज़ और सबसे अनुकूलित रास्ते के लिए, बस जावा

surfaceTexture = new SurfaceTexture(textureIDs[0]); 
try { 
    someCamera.setPreviewTexture(surfaceTexture); 
} catch (IOException t) { 
    Log.e(TAG, "Cannot set preview texture target!"); 
} 

someCamera.startPreview(); 

private static final int GL_TEXTURE_EXTERNAL_OES = 0x8D65; 

में आम जीएल Extention

//Fragment Shader 
#extension GL_OES_EGL_image_external : require 
uniform samplerExternalOES u_Texture; 

उपयोग की तुलना में जावा जीएल थ्रेड में

GLES20.glActiveTexture(GLES20.GL_TEXTURE0); 
GLES20.glBindTexture(GL_TEXTURE_EXTERNAL_OES, textureIDs[0]); 
GLES20.glUniform1i(uTextureHandle, 0); 

कलर रूपांतरण आपके लिए पहले से ही किया जा चुका है। आप फ्रैगमेंट शेडर में जो भी चाहें वह कर सकते हैं।

आशा है कि आपको अपने शोध में कुछ समय बचाएगा।

0

मैंने प्रश्न में साझा परियोजना के लिए समाधान फॉर्म How to render Android's YUV-NV21 camera image on the background in libgdx with OpenGLES 2.0 in real-time? लागू किया और एक कार्य प्रोजेक्ट प्राप्त किया। यदि आप मेरे जैसे ट्यूटोरियल कोड खोज रहे हैं जो कि यूजीवी को आरजीबी रूपांतरण से खंडित शेडर द्वारा करता है, तो आप कामकाजी उदाहरण प्राप्त करने के लिए निम्न चरणों को कर सकते हैं।

  1. प्रोजेक्ट https://dl.dropbox.com/u/12829395/application/FilterGL/FilterGL.zip डाउनलोड करें और अनजिप करें।
  2. फ़ाइल को बदलें GLRenderer.java और res/raw/f_convert.glsl पूरी तरह से नीचे दिए गए कोड द्वारा पूरी तरह से।
  3. ग्रहण में प्रोजेक्ट खोलें, या import the project to Android Studio

प्रश्न में कोड की मुख्य मुद्दे हैं:

  1. बिना GLES20.glActiveTexture (GLES20.GL_TEXTURE1);, वाईबीफर जीएल को पास नहीं किया गया है।
  2. वाईयूवी डेटा वाईयूवी-एनवी 21 प्रारूप लेता है, और u_texture और v_texture पारित नहीं किया गया था और शेडर में सही ढंग से संभाला गया था। अधिक जानकारी के लिए this post देखें।

अब सुधारा कोड: कृपया

package com.filtergl.shader; 

import java.io.BufferedReader; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import java.nio.ByteBuffer; 
import java.nio.ByteOrder; 
import java.nio.FloatBuffer; 
import java.nio.ShortBuffer; 

import javax.microedition.khronos.egl.EGLConfig; 
import javax.microedition.khronos.opengles.GL10; 

import android.content.Context; 
import android.hardware.Camera; 
import android.hardware.Camera.PreviewCallback; 
import android.opengl.GLES20; 
import android.opengl.GLSurfaceView.Renderer; 
import android.util.Log; 

public class GLRenderer 
implements Renderer, PreviewCallback { 
    private static final int LENGTH = 76800; 
    private static final int LENGTH_2 = 38400; 

    private ActivityFilterGL activity; 

    private FloatBuffer mVertices; 
    private ShortBuffer mIndices; 

    private int previewFrameWidth = 256; 
    private int previewFrameHeight = 256; 
    private int mProgramObject; 
    private int mPositionLoc; 
    private int mTexCoordLoc; 
// private int mSamplerLoc; 
    private int yTexture; 
    private int uTexture; 
    private int vTexture; 

    private final float[] mVerticesData = { -1.f, 1.f, 0.0f, // Position 0 
      0.0f, 0.0f, // TexCoord 0 
      -1.f, -1.f, 0.0f, // Position 1 
      0.0f, 1.0f, // TexCoord 1 
      1.f, -1.f, 0.0f, // Position 2 
      1.0f, 1.0f, // TexCoord 2 
      1.f, 1.f, 0.0f, // Position 3 
      1.0f, 0.0f // TexCoord 3 
    }; 

    private final short[] mIndicesData = { 0, 1, 2, 0, 2, 3 }; 

    private ByteBuffer frameData = null; 
    private ByteBuffer yBuffer; 
    private ByteBuffer uBuffer; 

    public GLRenderer(ActivityFilterGL activity) { 
     this.activity = activity; 

     mVertices = ByteBuffer.allocateDirect(mVerticesData.length * 4) 
       .order(ByteOrder.nativeOrder()).asFloatBuffer(); 
     mVertices.put(mVerticesData).position(0); 

     mIndices = ByteBuffer.allocateDirect(mIndicesData.length * 2) 
       .order(ByteOrder.nativeOrder()).asShortBuffer(); 
     mIndices.put(mIndicesData).position(0); 

     yBuffer = GraphicsUtil.makeByteBuffer(LENGTH); 
     uBuffer = GraphicsUtil.makeByteBuffer(LENGTH_2); 
    } 

    @Override 
    public final void onDrawFrame(GL10 gl) { 
     // Clear the color buffer 
     GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT); 

     // Use the program object 
     GLES20.glUseProgram(mProgramObject); 

     // Load the vertex position 
     mVertices.position(0); 
     GLES20.glVertexAttribPointer(mPositionLoc, 3, GLES20.GL_FLOAT, false, 5 * 4, mVertices); 
     // Load the texture coordinate 
     mVertices.position(3); 
     GLES20.glVertexAttribPointer(mTexCoordLoc, 2, GLES20.GL_FLOAT, false, 5 * 4, mVertices); 

     GLES20.glEnableVertexAttribArray(mPositionLoc); 
     GLES20.glEnableVertexAttribArray(mTexCoordLoc); 

     GLES20.glActiveTexture(GLES20.GL_TEXTURE1); 

     GLES20.glUniform1i(yTexture, 1); 
     GLES20.glTexImage2D( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE, 
       320, 240, 0, GLES20.GL_LUMINANCE, GLES20.GL_UNSIGNED_BYTE, yBuffer); 
     GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 
     GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 
     GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 
     GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 

     GLES20.glActiveTexture(GLES20.GL_TEXTURE2); 

     GLES20.glUniform1i(uTexture, 2); 
     GLES20.glTexImage2D( GLES20.GL_TEXTURE_2D, 0, GLES20.GL_LUMINANCE_ALPHA, 
       160, 120, 0, GLES20.GL_LUMINANCE_ALPHA, GLES20.GL_UNSIGNED_BYTE, uBuffer); 
     GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_LINEAR); 
     GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_LINEAR); 
     GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); 
     GLES20.glTexParameterf(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); 

     GLES20.glDrawElements(GLES20.GL_TRIANGLES, 6, GLES20.GL_UNSIGNED_SHORT, mIndices); 
    } 

    @Override 
    public void onSurfaceChanged(GL10 gl, int width, int height) { 
     GLES20.glViewport(0, 0, width, height); 
    } 

    @Override 
    public void onSurfaceCreated(GL10 gl, EGLConfig config) { 

     // Define a simple shader program for our point. 
     final String vShaderStr = readTextFileFromRawResource(activity, R.raw.v_simple); 
     final String fShaderStr = readTextFileFromRawResource(activity, R.raw.f_convert); 

     // Load the shaders and get a linked program object 
     mProgramObject = loadProgram(vShaderStr, fShaderStr); 

     // Get the attribute locations 
     mPositionLoc = GLES20.glGetAttribLocation(mProgramObject, "a_position"); 
     mTexCoordLoc = GLES20.glGetAttribLocation(mProgramObject, "a_texCoord"); 

     GLES20.glEnable(GLES20.GL_TEXTURE_2D); 
     yTexture = GLES20.glGetUniformLocation(mProgramObject, "y_texture"); 
     int[] yTextureNames = new int[1]; 
     GLES20.glGenTextures(1, yTextureNames, 0); 
     int yTextureName = yTextureNames[0]; 
     GLES20.glActiveTexture(GLES20.GL_TEXTURE1); 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, yTextureName); 

     GLES20.glEnable(GLES20.GL_TEXTURE_2D); 
     uTexture = GLES20.glGetUniformLocation(mProgramObject, "u_texture"); 
     int[] uTextureNames = new int[1]; 
     GLES20.glGenTextures(1, uTextureNames, 0); 
     int uTextureName = uTextureNames[0]; 
     GLES20.glActiveTexture(GLES20.GL_TEXTURE2); 
     GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, uTextureName); 

     // Set the background clear color to black. 
     GLES20.glClearColor(1.0f, 0.0f, 0.0f, 0.0f); 
    } 

    public void setPreviewFrameSize(int realWidth, int realHeight) { 
     previewFrameHeight = realHeight; 
     previewFrameWidth = realWidth; 

//  frameData = GraphicsUtil.makeByteBuffer(previewFrameHeight * previewFrameWidth * 3); 
    } 

    public static String readTextFileFromRawResource(final Context context, final int resourceId) { 
     final InputStream inputStream = context.getResources().openRawResource(resourceId); 
     final InputStreamReader inputStreamReader = new InputStreamReader(inputStream); 
     final BufferedReader bufferedReader = new BufferedReader(inputStreamReader); 

     String nextLine; 
     final StringBuilder body = new StringBuilder(); 

     try { 
      while ((nextLine = bufferedReader.readLine()) != null) { 
       body.append(nextLine); 
       body.append('\n'); 
      } 
     } catch (IOException e) { 
      return null; 
     } 

     return body.toString(); 
    } 

    public static int loadShader(int type, String shaderSrc) { 
     int shader; 
     int[] compiled = new int[1]; 

     // Create the shader object 
     shader = GLES20.glCreateShader(type); 
     if (shader == 0) { 
      return 0; 
     } 
     // Load the shader source 
     GLES20.glShaderSource(shader, shaderSrc); 
     // Compile the shader 
     GLES20.glCompileShader(shader); 
     // Check the compile status 
     GLES20.glGetShaderiv(shader, GLES20.GL_COMPILE_STATUS, compiled, 0); 

     if (compiled[0] == 0) { 
      Log.e("ESShader", GLES20.glGetShaderInfoLog(shader)); 
      GLES20.glDeleteShader(shader); 
      return 0; 
     } 
     return shader; 
    } 

    public static int loadProgram(String vertShaderSrc, String fragShaderSrc) { 
     int vertexShader; 
     int fragmentShader; 
     int programObject; 
     int[] linked = new int[1]; 

     // Load the vertex/fragment shaders 
     vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertShaderSrc); 
     if (vertexShader == 0) { 
      return 0; 
     } 

     fragmentShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragShaderSrc); 
     if (fragmentShader == 0) { 
      GLES20.glDeleteShader(vertexShader); 
      return 0; 
     } 

     // Create the program object 
     programObject = GLES20.glCreateProgram(); 

     if (programObject == 0) { 
      return 0; 
     } 

     GLES20.glAttachShader(programObject, vertexShader); 
     GLES20.glAttachShader(programObject, fragmentShader); 

     // Link the program 
     GLES20.glLinkProgram(programObject); 

     // Check the link status 
     GLES20.glGetProgramiv(programObject, GLES20.GL_LINK_STATUS, linked, 0); 

     if (linked[0] == 0) { 
      Log.e("ESShader", "Error linking program:"); 
      Log.e("ESShader", GLES20.glGetProgramInfoLog(programObject)); 
      GLES20.glDeleteProgram(programObject); 
      return 0; 
     } 

     // Free up no longer needed shader resources 
     GLES20.glDeleteShader(vertexShader); 
     GLES20.glDeleteShader(fragmentShader); 

     return programObject; 
    } 

    @Override 
    public void onPreviewFrame(byte[] data, Camera camera) { 
     yBuffer.put(data, 0, LENGTH); 
     yBuffer.position(0); 

     uBuffer.put(data, LENGTH, LENGTH/2); 
     uBuffer.position(0); 
    } 

} 

साथ GLRenderer.java की जगह और

#ifdef GL_ES 
precision highp float; 
#endif 

varying vec2 v_texCoord; 
uniform sampler2D y_texture; 
uniform sampler2D u_texture; 

void main() 
{ 
    float r, g, b, y, u, v; 

    //We had put the Y values of each pixel to the R,G,B components by 
    //GL_LUMINANCE, that's why we're pulling it from the R component, 
    //we could also use G or B 
    y = texture2D(y_texture, v_texCoord).r; 

    //We had put the U and V values of each pixel to the A and R,G,B 
    //components of the texture respectively using GL_LUMINANCE_ALPHA. 
    //Since U,V bytes are interspread in the texture, this is probably 
    //the fastest way to use them in the shader 
    u = texture2D(u_texture, v_texCoord).a - 0.5; 
    v = texture2D(u_texture, v_texCoord).r - 0.5; 

    //The numbers are just YUV to RGB conversion constants 
    r = y + 1.13983*v; 
    g = y - 0.39465*u - 0.58060*v; 
    b = y + 2.03211*u; 

    gl_FragColor = vec4(r,g,b,1.0); 
} 
साथ f_convert.glsl की जगह
संबंधित मुद्दे