Hi

I need some help with the following problem.

I took the hello-gl2 example from the android-ndk and rewrote a bit to 
suite my needs.
The GL2JNIView class is the same except the init function where I added
        setRenderMode(RENDERMODE_WHEN_DIRTY);

In the Render class onSurfaceChanged function I call the native 
method setupGraphics(int w, int h)  (see attached file)
In the Render class onDrawFrame function i call the native method void 
render(jbyteArray bArray) (bArray contains a jpg image with some other data)

I'm using the GL2JNIView inside a Fragment that is displayed at user 
request. The GL2JNIView is created in the Fragments onCreateView and added 
to a FrameLayout.

This all works fine except the first time the Fragment is displayed I get 
the following error:

after glUseProgram() glError (0x501)
eglSwapBuffers failed: EGL_BAD_SURFACE

The error is thrown in native render function after the line 
glUseProgram(gProgram).

If I remove the Fragment (with FragmentManager) and display it again there 
is no error and all working fine.

I did a small hack that actually fixes this but I don't like it:
After calling first time the render function (calling requestRender() on 
GL2JNIView) I remove the GL2JNIView from layout, create it again and add it 
again to FrameLayout.

I try this on Nexus 7 running latest stock Android and on Samsung Galaxy S2 
runing CM9.1. Same result on both devices.

Is there someone who could help me with this.

Thanks

Zoltan

-- 
You received this message because you are subscribed to the Google
Groups "Android Developers" group.
To post to this group, send email to [email protected]
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/android-developers?hl=en
int screenWidth;
int screenHeight;
GLuint gProgram;
GLuint gvPositionHandle;
GLuint gvTexCoordHandle;
GLuint gvSamplerHandle;


GLfloat vVertices[] = { -1.0f, 1.0f, 0.0f, // Position 0
                        0.0f, 0.0f, // TexCoord 0
                        -1.0f, -1.0f, 0.0f, // Position 1
                        0.0f, 1.0f, // TexCoord 1
                        1.0f, -1.0f, 0.0f, // Position 2
                        1.0f, 1.0f, // TexCoord 2
                        1.0f, 1.0f, 0.0f, // Position 3
                        1.0f, 0.0f // TexCoord 3
                      };
GLushort indices[] = { 0, 1, 2, 0, 2, 3 };
GLsizei stride = 5 * sizeof(GLfloat); // 3 for position, 2 for texture

static const char gVertexShader[] = "attribute vec4 a_position;   \n"
                                    "attribute vec2 a_texCoord;   \n"
                                    "varying vec2 v_texCoord;     \n"
                                    "void main()                  \n"
                                    "{                            \n"
                                    "   gl_Position = a_position; \n"
                                    "   v_texCoord = a_texCoord;  \n"
                                    "}                            \n";

static const char gFragmentShader[] =
    "precision mediump float;                            \n"
    "varying vec2 v_texCoord;                            \n"
    "uniform sampler2D s_texture;                        \n"
    "void main()                                         \n"
    "{                                                   \n"
    "  gl_FragColor = texture2D( s_texture, v_texCoord );\n"
    "}                                                   \n";

GLuint loadShader(GLenum shaderType, const char* pSource) {
    GLuint shader = glCreateShader(shaderType);
    if (shader) {
        glShaderSource(shader, 1, &pSource, NULL);
        glCompileShader(shader);
        GLint compiled = 0;
        glGetShaderiv(shader, GL_COMPILE_STATUS, &compiled);
        if (!compiled) {
            GLint infoLen = 0;
            glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLen);
            if (infoLen) {
                char* buf = (char*) malloc(infoLen);
                if (buf) {
                    glGetShaderInfoLog(shader, infoLen, NULL, buf);
                    LOGE("Could not compile shader %d:\n%s\n",
                            shaderType, buf);
                    free(buf);
                }
                glDeleteShader(shader);
                shader = 0;
            }
        }
    }
    return shader;
}

GLuint createProgram(const char* pVertexSource, const char* pFragmentSource) {
    GLuint vertexShader = loadShader(GL_VERTEX_SHADER, pVertexSource);
    if (!vertexShader) {
        return 0;
    }

    GLuint pixelShader = loadShader(GL_FRAGMENT_SHADER, pFragmentSource);
    if (!pixelShader) {
        return 0;
    }

    GLuint program = glCreateProgram();
    if (program) {
        glAttachShader(program, vertexShader);
        checkGlError("glAttachShader");
        glAttachShader(program, pixelShader);
        checkGlError("glAttachShader");
        glLinkProgram(program);
        GLint linkStatus = GL_FALSE;
        glGetProgramiv(program, GL_LINK_STATUS, &linkStatus);
        if (linkStatus != GL_TRUE) {
            GLint bufLength = 0;
            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &bufLength);
            if (bufLength) {
                char* buf = (char*) malloc(bufLength);
                if (buf) {
                    glGetProgramInfoLog(program, bufLength, NULL, buf);
                    LOGE("Could not link program:\n%s\n", buf);
                    free(buf);
                }
            }
            glDeleteProgram(program);
            program = 0;
        }
    }
    return program;
}

bool setupGraphics(int w, int h) {
        LOGI("setupGraphics");

        screenWidth = w;
        screenHeight = h;

    printGLString("Version", GL_VERSION);
    printGLString("Vendor", GL_VENDOR);
    printGLString("Renderer", GL_RENDERER);
    printGLString("Extensions", GL_EXTENSIONS);

    LOGI("setupGraphics(%d, %d)", w, h);
    gProgram = createProgram(gVertexShader, gFragmentShader);
    if (!gProgram) {
        LOGE("Could not create program.");
        return false;
    }
    gvPositionHandle = glGetAttribLocation(gProgram, "a_position");
    gvTexCoordHandle = glGetAttribLocation(gProgram, "a_texCoord");

    gvSamplerHandle = glGetAttribLocation(gProgram, "s_texture");

    // Use tightly packed data
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

    checkGlError("glGetAttribLocation");
    LOGI("glGetAttribLocation(\"vPosition\") = %d\n",
         gvPositionHandle);

    glViewport(0, 0, w, h);
    checkGlError("glViewport");


    return true;

}

// convert the Mat to a texture

GLuint createSimpleTexture2D(GLubyte* pixels,
        int width, int height, int channels) {

        
        // Generate a number for our textureID's unique handle
        GLuint tmpTextureId;
        glGenTextures(1, &tmpTextureId);

        // Bind the texture
        glActiveTexture(GL_TEXTURE0);
        checkGlError("glActiveTexture");

        // Bind to our texture handle
        glBindTexture(GL_TEXTURE_2D, tmpTextureId);
        checkGlError("glBindTexture");

        GLenum format;
        switch (channels) {
                case 3:
                        //format = 0x80e0; // GL_BGR
                        format = GL_RGB;
                        break;
                case 1:
                        format = GL_LUMINANCE;
                        break;
                case 4:
                        format = GL_RGBA;
                        break;
        }
        // Load the texture
        glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, 
format,GL_UNSIGNED_BYTE, pixels);
        checkGlError("glTexImage2D");

        // Set the filtering mode
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);

        // Set texture clamping method
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);


        return tmpTextureId;

}
void render(jbyteArray bArray)
{
    // here is the bArray conversion to OpenCV Mat
    // after processing oirg contains the the image


    Mat dest;

    // resize
    cv::resize(orig, dest, Size(512,512), 0, 0, cv::INTER_NEAREST);
    // convert from BGR to RGB
    cv::cvtColor(dest, dest, CV_BGR2RGB);

    // create texture
    GLuint matText = createSimpleTexture2D(dest.data, dest.cols, dest.rows, 
dest.channels());


    glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
    checkGlError("glClearColor");

    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    checkGlError("glClear");

    glUseProgram(gProgram);
    checkGlError("glUseProgram");

    // Load the vertex position
    glVertexAttribPointer(gvPositionHandle, 3, GL_FLOAT, GL_FALSE, stride,
                          vVertices);
    // Load the texture coordinate
    glVertexAttribPointer(gvTexCoordHandle, 2, GL_FLOAT, GL_FALSE, stride,
                          &vVertices[3]);

    glEnableVertexAttribArray(gvPositionHandle);
    glEnableVertexAttribArray(gvTexCoordHandle);

    // Bind the texture
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, matText);

    // Set the sampler texture unit to 0
    glUniform1i(gvSamplerHandle, 0);

    glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, indices);

    glDeleteTextures(1, &matText);
}

Reply via email to