Log in or register to post comments

OpenGL basics

May 29, 2011 - 2:15pm #1

Hi,

i'm new to OpenGL and try to learn some basics as described on http://iphonedevelopment.blogspot.com/2009/05/opengl-es-from-ground-up-table-of.html. But it doesn't work, so I have some questions.

  1. Where and how I should modify the ImageTargets example to draw a permanent visible triangle in the middle of a screen as described in this tutorial: http://iphonedevelopment.blogspot.com/2009/04/opengl-es-from-ground-up-part-2-look-at.html.
  2. How to move the triangle to the middle of a recognized image target?
  3. How to replace the triangle with a texture like green_glow.png or blue_glow.png from dominoes example?

Alex

Re: OpenGL basics

May 31, 2011 - 2:10pm #5

Thanks, you definitely made my day!

Alex

Re: OpenGL basics

May 31, 2011 - 11:34am #4

Try something like this:

GLfloat triangle[] = {0.0, 1.0, 0.0,  -1.0, 0.0, 0.0,  1.0, 0.0, 0.0};
glScalef(50.0f, 50.0f, 50.0f);
// Draw object:
glVertexPointer(3, GL_FLOAT, 0, &triangle);
glDrawArrays(GL_TRIANGLES, 0, 3);

There were three issues:

1) Your triangle was lifted off the target in the positive Z direction, and with a scale it flew out of view. See the Dev Guide > Trackables section for a diagram of the QCAR coordinate system (+Z is up and out of the target).

2) Your triangle was winding in the wrong direction. If GL_CULL_FACE is enabled, triangles must wind counterclockwise by default or won't be rendered: http://www.khronos.org/opengles/sdk/1.1/docs/man/glFrontFace.xml

3) glDrawArrays takes the number of vertices, not the size of the float array (so 3 instead of 9). It might work with the larger number, but can cause a crash.

Let me know if you have any questions,

- Kim

Re: OpenGL basics

May 30, 2011 - 3:40pm #3

Thank you for your answer.

I use OpenGL ES 1.x.

I've managed it to draw a triangle in the world space with this code:

JNIEXPORT void JNICALL
Java_com_qualcomm_QCARSamples_ImageTargets_ImageTargetsRenderer_renderFrame(JNIEnv *, jobject) {
    // Clear color and depth buffer 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    // Render video background:
    QCAR::State state = QCAR::Renderer::getInstance().begin();

    // Set GL11 flags:
    glEnableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);
    glDisable(GL_LIGHTING);

    glDisable(GL_TEXTURE_2D);
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_CULL_FACE);

    // Did we find any trackables this frame?
    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());

        // Load projection matrix:
        glMatrixMode(GL_PROJECTION);
        glLoadMatrixf(projectionMatrix.data);

        // Load model view matrix:
        glMatrixMode(GL_MODELVIEW);
        glLoadIdentity();

        // Set the color to red:
        glColor4f(1.0f, 0.0f, 0.0f, 1.0f);

        GLfloat triangle[] = {0.0, 1.0, +3.0, 1.0, 0.0, +3.0, -1.0, 0.0, +3.0};
        glScalef(0.1, 0.1, 1.0);
        // Draw object:
        glVertexPointer(3, GL_FLOAT, 0, &triangle);
        glDrawArrays(GL_TRIANGLES, 0, 9);
    }

    glDisable(GL_DEPTH_TEST);
    glDisable(GL_TEXTURE_2D);
    glDisableClientState(GL_VERTEX_ARRAY);
    glDisableClientState(GL_NORMAL_ARRAY);
    glDisableClientState(GL_TEXTURE_COORD_ARRAY);

    QCAR::Renderer::getInstance().end();
}

But if I replace glLoadIdentity() with glLoadMatrixf(modelViewMatrix.data) to move the triangle into the target space I get strange results. Experiments with glScalef() don't solve the problem. Could someone explain why?

- Alex

Re: OpenGL basics

May 30, 2011 - 5:46am #2

The first thing to understand is that those samples use OpenGL ES 1.x, rather than 2.0. Our ImageTargets sample has code paths for either version, but defaults to 2.0. You can change it to compile against the 1.x libraries by opening the Android.mk file and setting USE_OPENGL_ES_1_1 to true.

After that, you should be able to replace the code in the ImageTargets.cpp renderFrame() method to do your rendering. If you use the projection and modelview matrices set up in the sample, the object you draw will be in the target's space. You'll need to scale up the triangle with a glScalef call though, as the target is much larger than the triangle in that sample (the target is 247 units across, you can find that in the config.xml file).

To replace the texture, drop the texture file in the project's assets folder, and add it to the list of textures loaded in ImageTargets.java. Then look at the sample code, you can load it by its position in the list:

int textureIndex = 2;  // if you added to the end of the existing list
const Texture* const thisTexture = textures[textureIndex];
glBindTexture(GL_TEXTURE_2D, thisTexture->mTextureID);

- Kim

Log in or register to post comments