2013-03-27 104 views
9

我正在使用Vuforia將3D模型放置在圖像目標上。我已經創建了一個通用的C++解決方案,可以在Android和iOS上工作。它適用於Android,但我無法讓3D模型出現在iOS中。它完美地跟蹤圖像目標,但沒有3D模型的標誌。我正在使用的3D模型可以找到here渲染時不會出現3D模型

這是我正在做的:

此方法由Vuforia每一個需要被呈現在屏幕時稱爲:

- (void)renderFrameQCAR 
{ 
    [self setFramebuffer]; 
    [[ObjectController getInstance] getObjectInstance]->renderFrame(); 
    [self presentFramebuffer]; 
} 

這是setFramebuffer法(的Objective-C++):

- (void)setFramebuffer 
{ 
    if (context) { 
     [EAGLContext setCurrentContext:context]; 

     if (!defaultFramebuffer) { 
      [self performSelectorOnMainThread:@selector(createFramebuffer) withObject:self waitUntilDone:YES]; 
     } 

#ifdef USE_OPENGL1 
     glBindFramebufferOES(GL_FRAMEBUFFER_OES, defaultFramebuffer); 
#else 
     glBindFramebuffer(GL_FRAMEBUFFER, defaultFramebuffer); 
#endif 
    } 
} 

這是renderFrame方法(C++):

void IDRObject::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(); 

#ifdef DEVICE_OPENGL_1 
    // Set GL11 flags: 
    glEnableClientState(GL_VERTEX_ARRAY); 
    glEnableClientState(GL_NORMAL_ARRAY); 
    glEnableClientState(GL_TEXTURE_COORD_ARRAY); 

    glEnable(GL_TEXTURE_2D); 
    glDisable(GL_LIGHTING); 

#endif 

    glEnable(GL_DEPTH_TEST); 

    // We must detect if background reflection is active and adjust the culling direction. 
    // If the reflection is active, this means the post matrix has been reflected as well, 
    // therefore standard counter clockwise face culling will result in "inside out" models. 
    glEnable(GL_CULL_FACE); 
    glCullFace(GL_BACK); 
    if(QCAR::Renderer::getInstance().getVideoBackgroundConfig().mReflection == QCAR::VIDEO_BACKGROUND_REFLECTION_ON) 
     glFrontFace(GL_CW); //Front camera 
    else 
     glFrontFace(GL_CCW); //Back camera 

    SampleUtils::checkGlError("gl start setup stuff"); 
    // Did we find any trackables this frame? 
    for(int tIdx = 0; tIdx < state.getNumTrackableResults(); tIdx++) 
    { 
     // Get the trackable: 
     const QCAR::TrackableResult* result = state.getTrackableResult(tIdx); 
     const QCAR::Trackable& trackable = result->getTrackable(); 
     QCAR::Matrix44F modelViewMatrix = QCAR::Tool::convertPose2GLMatrix(result->getPose()); 

     // Choose the texture based on the target name: 
     int textureIndex; 
     if (strcmp(trackable.getName(), "chips") == 0) 
     { 
      textureIndex = 0; 
     } 
     else if (strcmp(trackable.getName(), "stones") == 0) 
     { 
      textureIndex = 1; 
     } 
     else 
     { 
      textureIndex = 2; 
     } 

     const Texture* const thisTexture = textures[textureIndex]; 

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

     // Load model view matrix: 
     glMatrixMode(GL_MODELVIEW); 
     glLoadMatrixf(modelViewMatrix.data); 
     glTranslatef(0.f, 0.f, kObjectScale); 
     glScalef(kObjectScale, kObjectScale, kObjectScale); 

     // Draw object: 
     glBindTexture(GL_TEXTURE_2D, thisTexture->mTextureID); 
     glTexCoordPointer(2, GL_FLOAT, 0, (const GLvoid*) &teapotTexCoords[0]); 
     glVertexPointer(3, GL_FLOAT, 0, (const GLvoid*) &teapotVertices[0]); 
     glNormalPointer(GL_FLOAT, 0, (const GLvoid*) &teapotNormals[0]); 
     glDrawElements(GL_TRIANGLES, NUM_TEAPOT_OBJECT_INDEX, GL_UNSIGNED_SHORT, 
        (const GLvoid*) &teapotIndices[0]); 

#else 


     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); 

     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]); 

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

     glActiveTexture(GL_TEXTURE0); 
     glBindTexture(GL_TEXTURE_2D, thisTexture->mTextureID); 

     glUniformMatrix4fv(mvpMatrixHandle, 1, GL_FALSE, (GLfloat*)&modelViewProjection.data[0]); 
     glUniform1i(texSampler2DHandle, 0 /*GL_TEXTURE0*/); 
     glDrawElements(GL_TRIANGLES, NUM_TEAPOT_OBJECT_INDEX, GL_UNSIGNED_SHORT, (const GLvoid*) &teapotIndices[0]); 

     LOG("Tracking awesome targets.\n"); 
     SampleUtils::checkGlError("ImageTargets renderFrame\n"); 
#endif 

    } 

    glDisable(GL_DEPTH_TEST); 
    glDisable(GL_CULL_FACE); 

#ifdef DEVICE_OPENGL_1 
    glDisable(GL_TEXTURE_2D); 
    glDisableClientState(GL_VERTEX_ARRAY); 
    glDisableClientState(GL_NORMAL_ARRAY); 
    glDisableClientState(GL_TEXTURE_COORD_ARRAY); 
#else 
    glDisableVertexAttribArray(vertexHandle); 
    glDisableVertexAttribArray(normalHandle); 
    glDisableVertexAttribArray(textureCoordHandle); 
#endif 

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

而最後presentFrameBuffer(的Objective-C++):

- (BOOL)presentFramebuffer 
{ 
    BOOL success = FALSE; 

    if (context) { 
     [EAGLContext setCurrentContext:context]; 

#ifdef USE_OPENGL1 
     glBindRenderbufferOES(GL_RENDERBUFFER_OES, colorRenderbuffer); 
#else 
     glBindRenderbuffer(GL_RENDERBUFFER, colorRenderbuffer); 
#endif 

     success = [context presentRenderbuffer:GL_RENDERBUFFER]; 
    } 

    return success; 
} 
+0

爲什麼你有'USE_OPENGL1'和'DEVICE_OPENGL_1'?這兩個是獨立的嗎? – 2013-03-27 10:48:38

+0

'DEVICE_OPENGL_1'用於放置'renderFrame'方法的C++庫中。 「USE_OPENGL1」用於調用框架的iOS應用程序。他們都會同時設置或不設置, – 2013-03-27 10:50:23

+0

嗯,儘量不要畫一個茶壺,而是一個單一的大紅色三角形(或類似的東西)來開始計算你的問題是渲染緩衝區還是視口映射或投影矩陣等。 – 2013-03-27 11:12:30

回答

1

原來的projectionMatrix從來沒有設置。

我錯過以下呼叫:

// Cache the projection matrix: 
const QCAR::CameraCalibration& cameraCalibration = QCAR::CameraDevice::getInstance().getCameraCalibration(); 
projectionMatrix = QCAR::Tool::getProjectionGL(cameraCalibration, 2.0f, 2500.0f); 

他們原本放在從Vuforia的ImageTarget樣品中的startCamera方法。

+0

你能發佈正確的代碼嗎? – 2013-03-28 15:37:05

+1

編輯我的文章,缺少代碼:) – 2013-03-28 17:03:17