Question

I'm developing an iOS app using Vuforia iOS SDK (not the unity plugin).

I want to mix the VideoPlayback and ImageTargets sample together. From the forum suggestion I started with the videoplayback sample and integrate imageTarget on it. After editing the EAGLView files the app gets both video and 3D model but doesn't show the 3D model. When the image is tracked, it gets the 3D object inside renderFrameQCAR and prints log.

I can't understand where to look at. Has anyone tried and done this without Unity support? Any help is appreciated.

Was it helpful?

Solution 2

Start working on VideoPlayback project,change only in the EAGLView files for sample import the Teapot.h file in EAGLview.m

add code parts from ImageTargets the top within the namespace declaration:

const float kObjectScale = 3.0f;
const char* textureFilenames[] = {
    "icon_play.png",
    "icon_loading.png",
    "icon_error.png",
    "VuforiaSizzleReel_1.png",
    "VuforiaSizzleReel_2.png",

    // added for 3d model
    "TextureTeapotBrass.png",
    "TextureTeapotBlue.png",
    "TextureTeapotRed.png"
};

add this function (from ImageTargets)

- (void)setup3dObjects
{
for (int i=0; i < [textures count]; ++i) {
    Object3D* obj3D = [[Object3D alloc] init];
    if (i >= 5)
    {
        obj3D.numVertices = NUM_TEAPOT_OBJECT_VERTEX;
        obj3D.vertices = teapotVertices;
        obj3D.normals = teapotNormals;
        obj3D.texCoords = teapotTexCoords;
        obj3D.numIndices = NUM_TEAPOT_OBJECT_INDEX;
        obj3D.indices = teapotIndices;
    }
    obj3D.texture = [textures objectAtIndex:i];
    [objects3D addObject:obj3D];
    [obj3D release];
}
}

Then, in the RenderFrameQCAR, after:

int numActiveTrackables = state.getNumTrackableResults();

add codes for 3d model, comes from ImageTargets sample

for (int i = 0; i < state.getNumTrackableResults(); ++i) {
    // Get the trackable
    const QCAR::TrackableResult* result = state.getTrackableResult(i);
    const QCAR::Trackable& trackable = result->getTrackable();
    QCAR::Matrix44F modelViewMatrix = QCAR::Tool::convertPose2GLMatrix(result->getPose());

    // Choose the texture based on the target name
    int targetIndex = 0; // "stones"
    if (!strcmp(trackable.getName(), "chips"))
        targetIndex = 1;
    else if (!strcmp(trackable.getName(), "tarmac"))
        targetIndex = 2;
    Object3D *obj3D = [objects3D objectAtIndex:targetIndex+5];

    // OpenGL 2
    QCAR::Matrix44F modelViewProjection;
    ShaderUtils::translatePoseMatrix(0.0f, 0.0f, kObjectScale, &modelViewMatrix.data[0]);
    ShaderUtils::scalePoseMatrix(kObjectScale, kObjectScale, kObjectScale, &modelViewMatrix.data[0]);
    ShaderUtils::multiplyMatrix(&qUtils.projectionMatrix.data[0], &modelViewMatrix.data[0], &modelViewProjection.data[0]);
    glUseProgram(shaderProgramID);
    glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)obj3D.vertices);
    glVertexAttribPointer(normalHandle, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)obj3D.normals);
    glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)obj3D.texCoords);
    glEnableVertexAttribArray(vertexHandle);
    glEnableVertexAttribArray(normalHandle);
    glEnableVertexAttribArray(textureCoordHandle);
    glActiveTexture(GL_TEXTURE0);
    glBindTexture(GL_TEXTURE_2D, [obj3D.texture textureID]);
    glUniformMatrix4fv(mvpMatrixHandle, 1, GL_FALSE, (const GLfloat*)&modelViewProjection.data[0]);
    glUniform1i(texSampler2DHandle, 0 /*GL_TEXTURE0*/);
    glDrawElements(GL_TRIANGLES, obj3D.numIndices, GL_UNSIGNED_SHORT, (const GLvoid*)obj3D.indices);
    ShaderUtils::checkGlError("EAGLView renderFrameQCAR");
}

just ensure all your stuff loaded correctly, should work just fine.

OTHER TIPS

This answer is based on real experience.

I call the 3d model in the videoplayback call, i mean like this

if (strcmp(imageTarget.getName(), "affogato") == 0)
{
const int kObjectScale = 500;
[self secondSetup3dObjects];
playerIndex = 99;
const QCAR::TrackableResult* result = state.getTrackableResult(i);
QCAR::Matrix44F modelViewMatrix = QCAR::Tool::convertPose2GLMatrix(result->getPose());
int targetIndex = 9;
Object3D *obj3D = [objects3D objectAtIndex:targetIndex];
QCAR::Matrix44F modelViewProjection;
ShaderUtils::translatePoseMatrix(0.0f, 0.0f, 50.0f, &modelViewMatrix.data[0]);
ShaderUtils::scalePoseMatrix(kObjectScale, kObjectScale, kObjectScale, &modelViewMatrix.data[0]);
ShaderUtils::multiplyMatrix(&qUtils.projectionMatrix.data[0], &modelViewMatrix.data[0], &modelViewProjection.data[0]);
glUseProgram(shaderProgramID);
glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)obj3D.vertices);
glVertexAttribPointer(normalHandle, 3, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)obj3D.normals);
            glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0, (const GLvoid*)obj3D.texCoords);

glEnableVertexAttribArray(vertexHandle);
            glEnableVertexAttribArray(normalHandle);
            glEnableVertexAttribArray(textureCoordHandle);

            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, [obj3D.texture textureID]);
            glUniformMatrix4fv(mvpMatrixHandle, 1, GL_FALSE, (const GLfloat*)&modelViewProjection.data[0]);
            glUniform1i(texSampler2DHandle, 0 /*GL_TEXTURE0*/);
            glDrawArrays(GL_TRIANGLES, 0,  obj3D.numVertices);

            ShaderUtils::checkGlError("EAGLView renderFrameQCAR");

I hope this can help anyone...

Oh, BTW you need to put in the appdelegate a video to this target and a transparent Background to the texture to make this work like a charm Regards

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top