Reputation: 1
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
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