Log in or register to post comments

loading two 3d models on the same marker with different textures

November 13, 2012 - 6:59am #1

Hi, I'm new in developing AR app. I can load two different 3d models (virtualbuttons sample) on a single marker but I don't know how to assign them different textures. Both the models load the banana.png. Any suggestions? thanks

loading two 3d models on the same marker with different textures

November 14, 2012 - 9:17am #5

Hi realbruz,

in glBindTexture() you can put whatever texture id you want (so you don't have to use mThisTexture->mTextureID);

suppose you have an array with 10 textures (i.e. with 10 elements of class "Texture"); for each 3D model, you can choose one of those texture,

for instance:

Texture *textureForModel_A = textures[4];

Texture *textureForModel_B = textures[6];

The inidces "4" and 6" that I use in my example are just two example indices; just use the indices that you want, the choice is up to your specific application logic.

Of course, you can also use two arrays of textures if you prefer so, i.e. one texture array for "3D Model A" and another texture array for "3D model B", so that in that case you can use the same index in both arrays and get two different textures;

 

Whatever path you take, the functions that you will need to adjust are:

"_initApplicationNative" in ImageTargets.cpp (or VirtualButtons.cpp if you use the virtual buttons sample), where the textures are created using the Texture::create( ... ) method

and also make sure that you pass all the textures that you need from Java, by adjusting the code in loadTextures() method (in VirtualButton.java or ImageTargets.java epending on which sample you use as reference).

 

 

loading two 3d models on the same marker with different textures

November 14, 2012 - 4:31am #4

Hi, I would recommend to take a look on VirtualButtons.loadTextures Java method. Once you add new textures there they should show automatically on JNI side too and you can use indices higher than current textureIndex. Which is by default bound to value 4 at maximum.

loading two 3d models on the same marker with different textures

November 14, 2012 - 1:12am #3

I'm using the samplebutton sample, I need to load two 3d model on one marker, the code below do it. My problem is related to the texture of the second object. It should use a different array of textures. If it is not possible can you please post a sample code  to modify this call " glBindTexture(GL_TEXTURE_2D, thisTexture->mTextureID);" with a specific target ID?

JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_VirtualButtons_VirtualButtonsRenderer_renderFrame(JNIEnv *, jobject)
{
    //LOG("Java_com_qualcomm_QCARSamples_VirtualButtons_GLRenderer_renderFrame");
 
    // 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();
   
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);

    // Did we find any trackables this frame?
    if (state.getNumActiveTrackables())
    {
        // Get the trackable:
        const QCAR::Trackable* trackable = state.getActiveTrackable(0);
        QCAR::Matrix44F modelViewMatrix =
            QCAR::Tool::convertPose2GLMatrix(trackable->getPose());

        // The image target:
        assert(trackable->getType() == QCAR::Trackable::IMAGE_TARGET);
        const QCAR::ImageTarget* target =
            static_cast<const QCAR::ImageTarget*>(trackable);

        // Set transformations:
        QCAR::Matrix44F modelViewProjection;
        SampleUtils::multiplyMatrix(&projectionMatrix.data[0],
                                    &modelViewMatrix.data[0],
                                    &modelViewProjection.data[0]);
                                   
                                   
        // Set the texture used for the teapot model:
        int textureIndex = 0;
        GLfloat vbVertices[96];
        unsigned char vbCounter=0;

        // Iterate through this targets virtual buttons:
        for (int i = 0; i < target->getNumVirtualButtons(); ++i)
        {
            const QCAR::VirtualButton* button = target->getVirtualButton(i);

            // If the button is pressed, than use this texture:
            if (button->isPressed())
            {
                // Run through button name array to find texture index
                for (int j = 0; j < NUM_BUTTONS; ++j)
                {
                    if (strcmp(button->getName(), virtualButtonColors[j]) == 0)
                    {
                        textureIndex = j+1;
                        break;
                    }
                }
            }           
           
            const QCAR::Area* vbArea = &button->getArea();
            assert(vbArea->getType() == QCAR::Area::RECTANGLE);
            const QCAR::Rectangle* vbRectangle = static_cast<const QCAR::Rectangle*>(vbArea);

            // We add the vertices to a common array in order to have one single
            // draw call. This is more efficient than having multiple glDrawArray calls
            vbVertices[vbCounter   ]=vbRectangle->getLeftTopX();
            vbVertices[vbCounter+ 1]=vbRectangle->getLeftTopY();
            vbVertices[vbCounter+ 2]=0.0f;
            vbVertices[vbCounter+ 3]=vbRectangle->getRightBottomX();
            vbVertices[vbCounter+ 4]=vbRectangle->getLeftTopY();
            vbVertices[vbCounter+ 5]=0.0f;
            vbVertices[vbCounter+ 6]=vbRectangle->getRightBottomX();
            vbVertices[vbCounter+ 7]=vbRectangle->getLeftTopY();
            vbVertices[vbCounter+ 8]=0.0f;
            vbVertices[vbCounter+ 9]=vbRectangle->getRightBottomX();
            vbVertices[vbCounter+10]=vbRectangle->getRightBottomY();
            vbVertices[vbCounter+11]=0.0f;
            vbVertices[vbCounter+12]=vbRectangle->getRightBottomX();
            vbVertices[vbCounter+13]=vbRectangle->getRightBottomY();
            vbVertices[vbCounter+14]=0.0f;
            vbVertices[vbCounter+15]=vbRectangle->getLeftTopX();
            vbVertices[vbCounter+16]=vbRectangle->getRightBottomY();
            vbVertices[vbCounter+17]=0.0f;
            vbVertices[vbCounter+18]=vbRectangle->getLeftTopX();
            vbVertices[vbCounter+19]=vbRectangle->getRightBottomY();
            vbVertices[vbCounter+20]=0.0f;
            vbVertices[vbCounter+21]=vbRectangle->getLeftTopX();
            vbVertices[vbCounter+22]=vbRectangle->getLeftTopY();
            vbVertices[vbCounter+23]=0.0f;
            vbCounter+=24;
           
        }

        // We only render if there is something on the array
        if (vbCounter>0)
        {
            // Render frame around button
            glUseProgram(vbShaderProgramID);

            glVertexAttribPointer(vbVertexHandle, 3, GL_FLOAT, GL_FALSE, 0,
                (const GLvoid*) &vbVertices[0]);

            glEnableVertexAttribArray(vbVertexHandle);

            glUniformMatrix4fv(mvpMatrixHandle, 1, GL_FALSE,
                (GLfloat*)&modelViewProjection.data[0] );

            // We multiply by 8 because that's the number of vertices per button
            // The reason is that GL_LINES considers only pairs. So some vertices
            // must be repeated.
            glDrawArrays(GL_LINES, 0, target->getNumVirtualButtons()*8);

            SampleUtils::checkGlError("VirtualButtons drawButton");

            glDisableVertexAttribArray(vbVertexHandle);
        }

        // Assumptions:
        assert(textureIndex < textureCount);
        const Texture* const thisTexture = textures[textureIndex];                           

       
        // Scale 3D model
       /* QCAR::Matrix44F modelViewScaled = modelViewMatrix;
        SampleUtils::scalePoseMatrix(kTeapotScale, kTeapotScale, kTeapotScale,
                                     &modelViewScaled.data[0]);*/

               //change
        QCAR::Matrix44F modelViewScaled = modelViewMatrix;
        SampleUtils::scalePoseMatrix(kpaperaScale, kpaperaScale, kpaperaScale,
                                     &modelViewScaled.data[0]);
                                     

        QCAR::Matrix44F modelViewProjectionScaled;
        SampleUtils::multiplyMatrix(&projectionMatrix.data[0],
                                    &modelViewScaled.data[0],
                                    &modelViewProjectionScaled.data[0]);
                                   
                                   
                                   
                                   
        // Render 3D model
        glUseProgram(shaderProgramID);
 
 
        //change
        /*glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0,
                              (const GLvoid*) &teapotVertices[0]);
        glVertexAttribPointer(normalHandle, 3, GL_FLOAT, GL_FALSE, 0,
                              (const GLvoid*) &teapotNormals[0]);
        glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0,
                              (const GLvoid*) &teapotTexCoords[0]);*/
                             
                             
        glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0,
                              (const GLvoid*) &paperaVerts[0]);
        glVertexAttribPointer(normalHandle, 3, GL_FLOAT, GL_FALSE, 0,
                              (const GLvoid*) &paperaNormals[0]);
        glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0,
                              (const GLvoid*) &paperaTexCoords[0]);

        glEnableVertexAttribArray(vertexHandle);
        glEnableVertexAttribArray(normalHandle);
        glEnableVertexAttribArray(textureCoordHandle);
        textureIndex=1;
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, thisTexture->mTextureID);
        glUniformMatrix4fv(mvpMatrixHandle, 1, GL_FALSE,
                           (GLfloat*)&modelViewProjectionScaled.data[0] );
                          
        //change                  
        /*glDrawElements(GL_TRIANGLES, NUM_TEAPOT_OBJECT_INDEX, GL_UNSIGNED_SHORT,
                       (const GLvoid*) &teapotIndices[0]);*/
        glDrawArrays(GL_TRIANGLES, 0, paperaNumVerts);
       
          //change second model
       // QCAR::Matrix44F modelViewMatrix = QCAR::Tool::convertPose2GLMatrix(trackable->getPose());
       
        SampleUtils::translatePoseMatrix(10.0f, 0.0f, kpaperaScale, &modelViewMatrix.data[0]);                              
                                                             
        // Render 3D model
        glUseProgram(shaderProgramID);
        // textureIndex = 2;                   
        glVertexAttribPointer(vertexHandle, 3, GL_FLOAT, GL_FALSE, 0,
                              (const GLvoid*) &paperaVerts[0]);
        glVertexAttribPointer(normalHandle, 3, GL_FLOAT, GL_FALSE, 0,
                              (const GLvoid*) &paperaNormals[0]);
        glVertexAttribPointer(textureCoordHandle, 2, GL_FLOAT, GL_FALSE, 0,
                              (const GLvoid*) &paperaTexCoords[0]);

        glEnableVertexAttribArray(vertexHandle);
        glEnableVertexAttribArray(normalHandle);
        glEnableVertexAttribArray(textureCoordHandle);
        //textureIndex=2;
        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, thisTexture->mTextureID);
        glUniformMatrix4fv(mvpMatrixHandle, 1, GL_FALSE,
                           (GLfloat*)&modelViewProjectionScaled.data[0] );
                          
        //change                  
        /*glDrawElements(GL_TRIANGLES, NUM_TEAPOT_OBJECT_INDEX, GL_UNSIGNED_SHORT,
                       (const GLvoid*) &teapotIndices[0]);*/
        glDrawArrays(GL_TRIANGLES, 0, paperaNumVerts);

        SampleUtils::checkGlError("VirtualButtons renderFrame");

    }

loading two 3d models on the same marker with different textures

November 13, 2012 - 9:17am #2

Hi, 

changing the texture applied to a model is done by caling:

glBindTexture(GL_TEXTURE_2D, thisTexture->mTextureID);

so, whenever you render the vertex array of a 3D model (see code starting with glVertexAttribPointer() and subsequent lines), you need to call glBindTexture() and pass the actual Texture ID of the texture that you want to apply.

The texture id can be taken from the Texture object, which is one of the elements of the textures[] array in the Imagetargets.cpp (or FrameMarkers.cpp if you are using the frame markers sample as a baseline).

 

Log in or register to post comments