Ali Sheykhi
Ali Sheykhi

Reputation: 1

My first arObject hide when tracking second imageTarget

I am developing a Flutter application with the Vuforia SDK engine, but I have an issue:

Why, when I track ImageTarget2 after ImageTarget1, does my first object, which is associated with ImageTarget1, hide, and the second object, which is associated with ImageTarget2, render? I want both objects to remain in the scene.

Here is my shader which is a rectangle :

GLuint
GLESRenderer::createRectangleShader() {
//    const char* vertexShaderSource =
//            "attribute vec4 a_Position;\n"
//            "uniform mat4 u_MVPMatrix;\n"
//            "void main() {\n"
//            "  gl_Position = u_MVPMatrix * a_Position;\n"
//            "}\n";

    // 1. Vertex Shader Source
    const char* vertexShaderSource =
            "attribute vec4 a_Position;\n"
            "attribute vec2 a_TexCoord;\n" // Add this line for texture coordinates
            "varying vec2 v_TexCoord;\n"
            "uniform mat4 u_MVPMatrix;\n"
            "void main() {\n"
            "  gl_Position = u_MVPMatrix * a_Position;\n"
            "  v_TexCoord = a_TexCoord;\n" // Pass texture coordinates to fragment shader
            "}\n";

    // 2. Fragment Shader Source
    const char* fragmentShaderSource =
            "precision mediump float;\n"
            "varying vec2 v_TexCoord;\n"
//            "uniform vec4 u_Color;\n"
            "uniform sampler2D u_Texture;\n"
            "void main() {\n"
//            "  gl_FragColor = u_Color;\n"
              "gl_FragColor = texture2D(u_Texture, v_TexCoord);"
            "}\n";

    // 3. Create Shaders
    GLuint vertexShader = glCreateShader(GL_VERTEX_SHADER);
    GLuint fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);

    // 4. Compile Shaders
    glShaderSource(vertexShader, 1, &vertexShaderSource, nullptr);
    glCompileShader(vertexShader);

    glShaderSource(fragmentShader, 1, &fragmentShaderSource, nullptr);
    glCompileShader(fragmentShader);

    // 5. Create Program and Link Shaders
    GLuint programID = glCreateProgram();
    glAttachShader(programID, vertexShader);
    glAttachShader(programID, fragmentShader);
    glLinkProgram(programID);
    // Check for linking errors (add error handling here)

    // 6. Delete Shaders (they are no longer needed)
    glDeleteShader(vertexShader);
    glDeleteShader(fragmentShader);
    return programID;
}

renderRectangle method:

void
GLESRenderer::renderRectangle(const VuMatrix44F& projectionMatrix, const VuMatrix44F& modelViewMatrix, GLuint textureId) {
    // 1. Define Rectangle Vertices
    static const GLfloat rectVertices[] = {
            -0.5f, -0.5f, 0.0f, // Bottom left
            0.5f, -0.5f, 0.0f, // Bottom right
            -0.5f,  0.5f, 0.0f, // Top left
            0.5f,  0.5f, 0.0f  // Top right
    };

    // Define Texture Coordinates
    static const GLfloat textureCoords[] = {
            0.0f, 0.0f, // Bottom left
            1.0f, 0.0f, // Bottom right
            0.0f, 1.0f, // Top left
            1.0f, 1.0f  // Top right
    };

    // 2. Create Shader Program (if not already created)
    GLuint shaderProgramID = createRectangleShader();

    // 3. Calculate ModelViewProjection Matrix
    VuMatrix44F modelViewProjectionMatrix;
    VuMatrix44F scaledModelViewMatrix;

    // Adjust scale and position as needed
    VuVector3F scaleVec{0.3f, 0.3f, 1.0f};
    VuVector3F positionVec{0.0f, 0.0f, 0.0f};

    scaledModelViewMatrix = vuMatrix44FScale(scaleVec, modelViewMatrix);
    scaledModelViewMatrix = vuMatrix44FTranslate(positionVec, scaledModelViewMatrix);
    modelViewProjectionMatrix = vuMatrix44FMultiplyMatrix(projectionMatrix, scaledModelViewMatrix);

    // 4. Enable Blending and Disable Depth Test
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
    glDisable(GL_DEPTH_TEST);

    // 5. Use Shader Program and Set Attributes
    glUseProgram(shaderProgramID);

    GLint vertexPositionHandle = glGetAttribLocation(shaderProgramID, "a_Position");
    glEnableVertexAttribArray(vertexPositionHandle);
    glVertexAttribPointer(vertexPositionHandle, 3, GL_FLOAT, GL_FALSE, 0, rectVertices);

    // Texture Coordinate Attribute
    GLint textureCoordHandle = glGetAttribLocation(shaderProgramID, "a_TexCoord");
    glEnableVertexAttribArray(textureCoordHandle);
    glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0, textureCoords);

    // MVP Matrix Uniform
    GLint mvpMatrixHandle = glGetUniformLocation(shaderProgramID, "u_MVPMatrix");
    glUniformMatrix4fv(mvpMatrixHandle, 1, GL_FALSE, (GLfloat*)modelViewProjectionMatrix.data);

    // Texture Sampler Uniform
    GLint textureSamplerHandle = glGetUniformLocation(shaderProgramID, "u_Texture");
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, textureId);
    glUniform1i(textureSamplerHandle, 0); // Texture unit 0

    GLint colorHandle = glGetUniformLocation(shaderProgramID, "u_Color");
    VuVector4F rectColor{0.0f, 1.0f, 0.0f, 0.5f}; // Green color
    glUniform4f(colorHandle, rectColor.data[0], rectColor.data[1], rectColor.data[2], rectColor.data[3]);

    // 6. Draw Rectangle
    glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

    // 7. Disable Attributes and Shader Program
    glDisableVertexAttribArray(vertexPositionHandle);
    glUseProgram(0);

    // 8. Restore GL States (if needed)
    glEnable(GL_DEPTH_TEST);
    glDisable(GL_BLEND);
}

renderImageTarget method :

void
GLESRenderer::renderImageTarget(VuMatrix44F &projectionMatrix, VuMatrix44F &modelViewMatrix,
                                VuMatrix44F &scaledModelViewMatrix,const char *target){

    VuMatrix44F scaledModelViewProjectionMatrix = vuMatrix44FMultiplyMatrix(
                    projectionMatrix,scaledModelViewMatrix );

    glEnable(GL_DEPTH_TEST);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

    float stateLineWidth;
    glGetFloatv(GL_LINE_WIDTH, &stateLineWidth);

    glUseProgram(mUniformColorShaderProgramID);

    glVertexAttribPointer(mUniformColorVertexPositionHandle, 3, GL_FLOAT, GL_TRUE, 0, (const GLvoid*)&squareVertices[0]);

    glEnableVertexAttribArray(mUniformColorVertexPositionHandle);

    glUniformMatrix4fv(mUniformColorMvpMatrixHandle, 1, GL_FALSE, &scaledModelViewProjectionMatrix.data[0]);

    // Draw translucent solid overlay
    // Color RGBA
    glUniform4f(mUniformColorColorHandle, 1.0, 0.0, 0.0, 0.1);
    glDrawElements(GL_TRIANGLES, NUM_SQUARE_INDEX, GL_UNSIGNED_SHORT, (const GLvoid*)&squareIndices[0]);

    // Draw solid outline
    glUniform4f(mUniformColorColorHandle, 1.0, 0.0, 0.0, 1.0);
    glLineWidth(4.0f);
    glDrawElements(GL_LINES, NUM_SQUARE_WIREFRAME_INDEX, GL_UNSIGNED_SHORT, (const GLvoid*)&squareWireframeIndices[0]);

    glDisableVertexAttribArray(mUniformColorVertexPositionHandle);

    GLESUtils::checkGlError("Render Image Target");

    glLineWidth(stateLineWidth);

    glDisable(GL_BLEND);
    glDisable(GL_DEPTH_TEST);

    if(target != nullptr){
        if (strcasecmp(target, "ref") == 0){
            renderRectangle(projectionMatrix, modelViewMatrix, mRefDeviceLayoutTextureUnit);
        } else {
            renderRectangle(projectionMatrix, modelViewMatrix, mOvenDeviceLayoutTextureUnit);
        }
    }

}

renderFrame method:

JNIEXPORT jboolean JNICALL
Java_com_smartboom_arengine_flutter_1smartboom_1ar_1engine_engine_vuforia_VuforiaARView_renderFrame(JNIEnv* /* env */, jobject /* this */)
{
    if (!controller.isARStarted())
    {
        return JNI_FALSE;
    }

    // Clear colour and depth buffers
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    int vbTextureUnit = 0;
    VuRenderVideoBackgroundData renderVideoBackgroundData;
    renderVideoBackgroundData.renderData = nullptr;
    renderVideoBackgroundData.textureData = nullptr;
    renderVideoBackgroundData.textureUnitData = &vbTextureUnit;
    double viewport[6];
    if (controller.prepareToRender(viewport, &renderVideoBackgroundData))
    {
        // Set viewport for current view
        glViewport(viewport[0], viewport[1], viewport[2], viewport[3]);

        auto renderState = controller.getRenderState();

        gWrapperData.renderer.renderVideoBackground(
                renderState.vbProjectionMatrix, renderState.vbMesh->pos, renderState.vbMesh->tex,
                renderState.vbMesh->numFaces, renderState.vbMesh->faceIndices, vbTextureUnit);

      /// for render world position that will be choose as engine configuration from flutter side
//      VuMatrix44F worldOriginProjection;
//      VuMatrix44F worldOriginModelView;
//      if (controller.getOrigin(worldOriginProjection, worldOriginModelView))
//      {
//          gWrapperData.renderer.renderWorldOrigin(worldOriginProjection, worldOriginModelView);
//      }

        VuMatrix44F trackableProjection;
        VuMatrix44F trackableModelView;
        VuMatrix44F trackableModelViewScaled;
//        VuImageInfo modelTargetGuideViewImage;
//        VuBool guideViewImageHasChanged;

        const char* resultTarget = controller.getImageTargetResult(trackableProjection, trackableModelView, trackableModelViewScaled);
        gWrapperData.renderer.renderImageTarget(trackableProjection, trackableModelView, trackableModelViewScaled,resultTarget);

//        if (controller.getModelTargetResult(trackableProjection, trackableModelView, trackableModelViewScaled))
//        {
//            gWrapperData.renderer.renderModelTarget(trackableProjection, trackableModelView, trackableModelViewScaled);
//        }
//        else if (controller.getModelTargetGuideView(trackableProjection, trackableModelView, modelTargetGuideViewImage,
//                                                    guideViewImageHasChanged))
//        {
//            gWrapperData.renderer.renderModelTargetGuideView(trackableProjection, trackableModelView, modelTargetGuideViewImage,
//                                                             guideViewImageHasChanged);
//        }

        if (gWrapperData.usingARCore)
        {
            accessFusionProviderPointers();
        }
    }
    controller.finishRender();
    return JNI_TRUE;
}

Upvotes: 0

Views: 37

Answers (1)

thesbyro
thesbyro

Reputation: 201

It could be that Engine only tracks one target at a time, as a default. I don't know about VUforia Engine SDK integration with Flutter, but you can set the number of simultaneous tracked images with the Engine API.

vuEngineSetMaximumSimultaneousTrackedImages(VuEngine* engine, int32_t maxNumberOfTargets);

Just note that only image-based targets support simultaneous tracking. Model Targets and Area Targets can only be tracked one at a time. This article has more information: Detect and track targets simultaenously.

Upvotes: 0

Related Questions