2012-04-11 4 views
8

내가 본 모든 튜토리얼은 항상 삼각형이나 큐브와 같은 단일 객체를 사용합니다. 하지만 어떻게 독립적으로 개별 객체를 조작 할 수 있는지는 분명하지 않습니다. 고정 함수 파이프 라인을 참조하고 pushmatrix와 popmatrix를 사용하는 자습서를 보았지만 프로그래밍 가능한 파이프 라인에서는 이러한 함수가 사라졌습니다. 아래는 init 함수와 화면에 하나의 삼각형을 그려 Z 축을 중심으로 회전시키는 draw 함수입니다. 다른 사람이 나에게 코드를 보여 주거나 의사 코드를 추가하여 두 번째 삼각형을 추가하고 다른 삼각형과 독립적으로이를 회전시킬 수 있습니까? 다른 축 또는 반대 방향으로 말합니까? 여기OpenGL ES 2.0에서 객체를 독립적으로 변형

들이 위치 :

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

제 삼각형을 묘화 한 후, 삼각형을 한 번 그릴 후 업로드 새로운 원하는 회전/위치로 새로운 MVP 행렬을 생성하고. 장면에서 원하는만큼 유니폼을 바꿀 수 있습니다.

이것은 푸시 앤 팝이하는 것과 유사하며 주어진 객체를 그리기 전에 활성 행렬을 변경하는 것입니다.

예 의사 :

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)에서 세 개의 삼각형 (1,0,0)을 당신을 떠날 것이며, (2,0,0).

+0

좀 더 명확하게 표현할 수 있습니까? 특히, 번역을 포함하도록 유니폼 MVPMatrix의 값을 변경하는 경우, 기존 위치의 삼각형을 그 위치로 이동하는 것뿐만 아니라 새 위치에 삼각형의 복사본을 그리는 방법을 어떻게 알 수 있습니까? – Legion

+1

일단 glDrawArrays를 통해 삼각형을 디스패치하면 완료됩니다. 변수를 더 이상 변경할 필요가 없습니다. 일단 무언가가 렌더링되면 움직일 수 없으므로 어떤 유니폼으로 바뀌어도 변경된 드로 콜이 적용됩니다. 당신의 이해를 돕기 위해 약간의 샘플 코드를 제 대답에 넣었습니다. – Tim

+0

@Legion이 새로운 설명과 설명으로 업데이트되었습니다. – Tim

관련 문제