Log in or register to post comments

Showing 2 Object Models with 2 Different Image Targets

October 30, 2012 - 12:44am #1

Hai Guys, i have a problem here.

i have done some basic things here, like change the 3d model to another object instead of a teapot, and change the image target to another picture instead of stone and chips. what i want to do next is showing 2 different objects with 2 different image targets simmultaneously .

In the image target sample, we just can show a teapot with different texture in 2 different image targets (in stoneandchip dataset). Although, actually i know it is only one teapot object  that have 2 textures. the point is how can i show 2 different object instead of one objects that have two textures.

Showing 2 Object Models with 2 Different Image Targets

October 31, 2012 - 1:35pm #6

at each iteration, the trackable is set to the following:

QCAR::Trackable *trackable = state.getActiveTrackable( tIdx );

so, there is no relationship between trackable at iteration tIdx = 0 and trackable at iteration tIdx = 1; every iteration (tIdx = 0, tIdx = 1, tIdx = 2 etc...) has its own trackable, and therefore its own pose (trackable->getPose()).

So, they all represents different objects.

Then, when you render an object at a certain iteration, you can use different vertexArrays depending on the name of the trackable at currrent iteration, i.e. something like the following code snippet:

for(int tIdx = 0; tIdx < state.getNumActiveTrackables(); tIdx++)

{

        // Get the trackable:

        const QCAR::Trackable* trackable = state.getActiveTrackable(tIdx);

        QCAR::Matrix44F modelViewMatrix =  QCAR::Tool::convertPose2GLMatrix(trackable->getPose());        

 

        QCAR::Matrix44F modelViewProjection;

        SampleUtils::translatePoseMatrix(0.0f, 0.0f, kObjectScale, &modelViewMatrix.data[0]);

        SampleUtils::scalePoseMatrix(kObjectScale, kObjectScale, kObjectScale,  &modelViewMatrix.data[0]);

        SampleUtils::multiplyMatrix(&projectionMatrix.data[0],   &modelViewMatrix.data[0] ,  &modelViewProjection.data[0]);

        glUseProgram(shaderProgramID);

 

        if (strcmp(trackable->getName(), "chips") == 0)

        {// if target is "chips" then we use nyancat mesh

            glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0,  (const GLvoid*) &nyancatVertices[0]);

            glVertexAttribPointer(texCoordHandle, 2, GL_FLOAT, GL_FALSE, 0,  (const GLvoid*) &nyancatTexCoords[0]);

            glVertexAttribPointer(normalHandle, 3, GL_FLOAT, GL_FALSE, 0,  (const GLvoid*) &nyancatNormals[0]);

          

        }

        else if (strcmp(trackable->getName(), "stones") == 0)

        {   //if target is "Stones" then we use banana mesh

             glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0,  (const GLvoid*) &bananaVertices[0]);
 
            glVertexAttribPointer(texCoordHandle, 2, GL_FLOAT, GL_FALSE, 0,  (const GLvoid*) &bananaTexCoords[0]);
 
            glVertexAttribPointer(normalHandle, 3, GL_FLOAT, GL_FALSE, 0,  (const GLvoid*) &bananaNormals[0]);
 
        }
 
       // etc ...
}
 

Showing 2 Object Models with 2 Different Image Targets

October 31, 2012 - 11:40am #5

oh, so that is the purpose of the loop.. it is handling one trackable for each iteration of the loop, isn't it? and the point the loop know how many our trackable is by this condition:

for(int tIdx = 0; tIdx < state.getNumActiveTrackables(); tIdx++)

but, i still miss something here (i don't know.. maybe it's because i'm really new with the QCAR libraries).

in the "for" loop, we declare an object trackable to provide access to our trackable that currently being tracked, one trackable for each iteration. and we must to get its pose then give it to modelViewMatrix object. is the next iteration it will reuse the trackable object to access our next trackable?

and how can be the loop will draw the different mesh in the next iteration if the way the opengl draw the mesh is by these codes?

glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0,
                                      (const GLvoid*) &nyancat3Verts[0]);
glVertexAttribPointer(normalHandle, 3, GL_FLOAT, GL_FALSE, 0,
                                      (const GLvoid*) &nyancat3Normals[0]);
glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0,
                                      (const GLvoid*) &nyancat3TexCoords[0]);

it will just draw another nyancat mesh for the next iteration, won't it? so am i must add those codes with another mesh below them like this?

glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0,
                                      (const GLvoid*) &nyancat3Verts[0]);
glVertexAttribPointer(normalHandle, 3, GL_FLOAT, GL_FALSE, 0,
                                      (const GLvoid*) &nyancat3Normals[0]);
glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0,
                                      (const GLvoid*) &nyancat3TexCoords[0]);

 

glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0,
                                      (const GLvoid*) &bananaVerts[0]);
glVertexAttribPointer(normalHandle, 3, GL_FLOAT, GL_FALSE, 0,
                                      (const GLvoid*) &bananaNormals[0]);
glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0,
                                      (const GLvoid*) &bananaTexCoords[0]);

let me know where i was wrong, because it's a little bit confusing me Frown

Showing 2 Object Models with 2 Different Image Targets

October 31, 2012 - 9:11am #4

Hi, indeed the to pieces of code are connected, basically the connection is represented by the modelViewMatrix, in which you set the Pose of the target; the modelViewMatrix is then used below to position the target in 3D space using OpenGL.

 

Now, what you have to do is the following:

at every iteration in the "for" loop, you get a different trackable, and for each trackable you get its pose; then in the OpenGL code that starts with glVertexAttribPointer, you basically tell OpenGL to draw a mesh (a vertex array);

so, for instance, if you are at the first iteration in the "for" loop, you can draw "nyancat" mesh (and this will use the Pose of the first trackable),

then in the second iteration (assuming you have more than one trackable detected), you can use a different mesh (i.e. other than nyancat, for instane you could add a second "bananaVertices" mesh and use that for the second trackable...)

So, basically you have to pass different vertex arrays (e.g. nyancat, banana, some other mesh,...) to the various glVertexAttribPointer functions, at each iteration of the loop (i.e. one for each different trackable).

 

Showing 2 Object Models with 2 Different Image Targets

October 30, 2012 - 10:02pm #3

Alessandro, did you mean this codes?

// Clear color and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

// Get the state from QCAR and mark the beginning of a rendering section
QCAR::State state = QCAR::Renderer::getInstance().begin();
   
// Explicitly render the Video Background
QCAR::Renderer::getInstance().drawVideoBackground();

for(int tIdx = 0; tIdx < state.getNumActiveTrackables(); tIdx++)
    {
        // Get the trackable:
        const QCAR::Trackable* trackable = state.getActiveTrackable(tIdx);
        QCAR::Matrix44F modelViewMatrix =
                      QCAR::Tool::convertPose2GLMatrix(trackable->getPose());
        ...

but i don't understand what these codes mean.. -,- but i know it must be has a relation with the codes below them

QCAR::Matrix44F modelViewProjection;

SampleUtils::translatePoseMatrix(0.0f, 0.0f, 150.f,
                                   &modelViewMatrix.data[0]);
SampleUtils::rotatePoseMatrix(90.f, 1.0f, 0.0f, 0.0f,
                                   &modelViewMatrix.data[0]);
SampleUtils::scalePoseMatrix(kObjectScale, kObjectScale, kObjectScale,
                                   &modelViewMatrix.data[0]);
SampleUtils::multiplyMatrix(&projectionMatrix.data[0],
                                    &modelViewMatrix.data[0] ,
                                    &modelViewProjection.data[0]);

glUseProgram(shaderProgramID);
        
glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0,
                              (const GLvoid*) &nyancat3Verts[0]);
glVertexAttribPointer(normalHandle, 3, GL_FLOAT, GL_FALSE, 0,
                              (const GLvoid*) &nyancat3Normals[0]);
glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0,
                              (const GLvoid*) &nyancat3TexCoords[0]);

what i'm supposed to do, to add more object besides nyancat?

Showing 2 Object Models with 2 Different Image Targets

October 30, 2012 - 1:33am #2

Hi, if you look at the _renderFrame function in ImageTargets.cpp, you'll see that for each Trackable detected in the State object

a teapot is rendered (see code from setting the modelview matrix using getPose() and down to glDrawElements() call);

So, the code to render more than one teapot is already in place in the sample, but you need to enable the support for multiple targets,i.e.:

in the function "_onQCARInitializedNative", add the following line of code:

QCAR::setHint(QCAR::HINT_MAX_SIMULTANEOUS_IMAGE_TARGETS, 2);

That should be sufficient to make it work with the Stones and the Chips targets together.

 

Then, if you want to render two different models (i.e. a "Teapot" for Stones and a "SomeOtherModel" for Chips), you'll need to replace the Teapot vertex arrays with the "SomeOtherMode;" vertex array.

You might want to have a look at this thread as well:

https://ar.qualcomm.at/content/replace-3d-model-different-3d-model

 

 

Log in or register to post comments