2012-04-11 3 views
8

私が見たすべてのチュートリアルでは、常に三角形や立方体のような単一のオブジェクトを使用しています。しかし、どうやって独立したオブジェクトを個別に操作できるかはわかりません。固定機能のパイプラインを参照し、pushmatrixとpopmatrixを使用するチュートリアルを見たことがありますが、プログラム可能なパイプラインではこれらの機能はなくなりました。以下は、画面上に単一の三角形を描き、それをZ軸の周りに回転させるinit関数とdraw関数です。他の三角形を独立して回転させて、コードを表示したり、擬似コードで別の三角形を追加したりすることはできますか?別の軸の周りに言ったり、反対の方向に言ったりしますか?ここでOpenGL ES 2.0で独立してオブジェクトを変形する

彼らは以下のとおりです。それをアップロードし、あなたの新しい所望の回転/位置に新しいMVPの行列を生成し、最初の三角形を描画した後

int Init(ESContext* esContext) 
{ 
    UserData* userData = (UserData *)esContext->userData; 
    const char *vShaderStr = 
     "attribute vec4 vPosition; \n" 
     "uniform mat4 MVPMatrix;" 
     "void main()    \n" 
     "{       \n" 
     " gl_Position = MVPMatrix * vPosition;\n" 
     "}       \n"; 

    const char *fShaderStr = 
     "precision mediump float; \n" 
     "void main()    \n" 
     "{       \n" 
     " gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); \n" 
     "}       \n"; 

    GLuint vertexShader; 
    GLuint fragmentShader; 
    GLuint programObject; 
    GLint linked; 
    GLfloat ratio = 320.0f/240.0f; 

    vertexShader = LoadShader(GL_VERTEX_SHADER, vShaderStr); 
    fragmentShader = LoadShader(GL_FRAGMENT_SHADER, fShaderStr); 

    programObject = glCreateProgram(); 

    if (programObject == 0) 
     return 0; 

    glAttachShader(programObject, vertexShader); 
    glAttachShader(programObject, fragmentShader); 

    glBindAttribLocation(programObject, 0, "vPosition"); 
    glLinkProgram(programObject); 
    glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &linked); 

    if (!linked) 
    { 
     GLint infoLen = 0; 
     glGetProgramiv(programObject, GL_INFO_LOG_LENGTH, &infoLen); 

     if (infoLen > 1) 
     { 
      char* infoLog = (char *)malloc(sizeof(char) * infoLen); 
      glGetProgramInfoLog(programObject, infoLen, NULL, infoLog); 

      free(infoLog); 
     } 

     glDeleteProgram(programObject); 
     return FALSE; 
    } 

    userData->programObject = programObject; 

    glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 

    glViewport(0, 0, esContext->width, esContext->height); 
    glClear(GL_COLOR_BUFFER_BIT); 


    glUseProgram(userData->programObject); 

    userData->angle = 0.0f; 
    userData->start = time(NULL); 
    userData->ProjMatrix = PVRTMat4::Perspective(ratio*2.0f, 2.0f, 3.0f, 7.0f, PVRTMat4::eClipspace::OGL, false, false); 
    userData->ViewMatrix = PVRTMat4::LookAtLH(PVRTVec3(0.0f, 0.0f, -3.0f), PVRTVec3(0.0f, 0.0f, 0.0f), PVRTVec3(0.0f, 1.0f, 0.0f)); 
    return TRUE; 
} 



void Draw(ESContext *esContext) 
{ 
    GLfloat vVertices[] = {0.0f, 0.5f, 0.0f, 
          -0.5f, -0.5f, 0.0f, 
          0.5f, -0.5f, 0.0f}; 

    GLint MVPHandle; 
    double timelapse; 

    PVRTMat4 MVPMatrix = PVRTMat4::Identity(); 
    UserData* userData = (UserData *)esContext->userData; 

    timelapse = difftime(time(NULL), userData->start) * 1000; 
    if(timelapse > 16.0f) //Maintain approx 60FPS 
    { 
     if (userData->angle > 360.0f) 
     { 
      userData->angle = 0.0f; 
     } 
     else 
     { 
      userData->angle += 0.1f; 
     } 
    } 

    userData->ModelMatrix = PVRTMat4::RotationZ(userData->angle); 

    MVPMatrix = userData->ViewMatrix * userData->ModelMatrix; 
    MVPMatrix = userData->ProjMatrix * MVPMatrix; 

    MVPHandle = glGetUniformLocation(userData->programObject, "MVPMatrix"); 
    glUniformMatrix4fv(MVPHandle, 1, FALSE, MVPMatrix.ptr()); 

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, vVertices); 
    glEnableVertexAttribArray(0); 

    glClear(GL_COLOR_BUFFER_BIT); 
    glDrawArrays(GL_TRIANGLES, 0, 3); 
    eglSwapBuffers(esContext->eglDisplay, esContext->eglSurface); 
} 

答えて

6

、その後、三角形をもう一度描きます。あなたはシーンの中で何回でもユニフォームを変えることができます。

これは、プッシュとポップがやっていることに似ていますが、特定のオブジェクトを描画する前にアクティブなマトリックスを変更しているだけです。

例の擬似コード:

MMatrix = identity; 
MVPMatrix = VPMatrix * MMatrix; 
glUniformMatrix4fv(MVPHandle, 1, FALSE, MVPMatrix.ptr()); 
glDrawArrays(GL_TRIANGLES, 0, 3); //draw triangle at 0,0,0 

MMatrix.translate(1,0,0); 
MVPMatrix = VPMatrix * MMatrix; 
glUniformMatrix4fv(MVPHandle, 1, FALSE, MVPMatrix.ptr()); 
glDrawArrays(GL_TRIANGLES, 0, 3); //draw triangle at 1,0,0 

MMatrix.translate(1,0,0); 
MVPMatrix = VPMatrix * MMatrix; 
glUniformMatrix4fv(MVPHandle, 1, FALSE, MVPMatrix.ptr()); 
glDrawArrays(GL_TRIANGLES, 0, 3); //draw triangle at 2,0,0 

..repeat for as many objects as you want.. 

はこれが(0,0,0)の3つの三角形、(1,0,0)であなたを残して、(2,0,0)します。

+0

もう少し明示できますか?具体的には、翻訳を含むように統一されたMVPMatrixの値を変更するだけで、既存の三角形をその場所に移動するのではなく、新しい場所に三角形のコピーを描画する方法をどのように知ることができますか? – Legion

+1

glDrawArraysを使って三角形をディスパッチすると、完了です。変数をそれ以上変更しても影響はありません。何かがレンダリングされると、「移動」することはできません。したがって、ユニフォームを変更すると、変更後に描画呼び出しが行われます。私はあなたの理解を助けるために私の答えに少しサンプルコードを入れました。 – Tim

+0

@Legionは新しいコメントと説明で更新されました – Tim

関連する問題