2012-04-11 31 views
8

Tất cả các hướng dẫn tôi đã nhìn thấy luôn luôn sử dụng một đối tượng duy nhất, như một hình tam giác hoặc khối lập phương. Nhưng nó không rõ ràng với tôi như thế nào tôi có thể độc lập thao tác các đối tượng riêng biệt. Tôi đã nhìn thấy một số hướng dẫn đề cập đến các đường ống chức năng cố định và sử dụng pushmatrix và popmatrix, nhưng với đường ống lập trình các chức năng này đã biến mất. Dưới đây là một hàm init và hàm vẽ vẽ một hình tam giác trên màn hình và xoay nó về trục Z. Ai đó có thể chỉ cho tôi mã, hoặc thậm chí mã giả để thêm một tam giác thứ hai và xoay nó một cách độc lập với tam giác khác không? Nói xung quanh một trục khác hoặc theo hướng ngược lại?Biến đổi các đối tượng độc lập trong OpenGL ES 2.0

Dưới đây là:

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

Trả lời

6

Sau khi vẽ hình tam giác đầu tiên, tạo ra một ma trận MVP mới với mong muốn mới xoay/vị trí của bạn, tải nó lên, và sau đó vẽ hình tam giác một lần thứ hai. Bạn có thể thay đổi đồng phục nhiều lần tùy thích trong cảnh.

Điều này tương tự như những gì push và pop đang làm, chúng chỉ thay đổi ma trận hoạt động trước khi vẽ một đối tượng nhất định.

Ví dụ giả:

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.. 

này sẽ để lại cho bạn với ba hình tam giác, tại (0,0,0), (1,0,0), và (2,0,0).

+0

Bạn có thể rõ ràng hơn một chút không? Cụ thể, nếu tôi chỉ thay đổi giá trị của MVPMatrix thống nhất để bao gồm một bản dịch, làm thế nào nó sẽ biết vẽ một bản sao của tam giác ở vị trí mới, và không chỉ di chuyển tam giác hiện tại đến vị trí đó? – Legion

+1

Khi bạn gửi một hình tam giác qua glDrawArrays, nó được thực hiện. Không có thay đổi nào cho bất kỳ biến nào sẽ có bất kỳ ảnh hưởng nào đối với nó. Khi một cái gì đó đã được trả lại nó không thể được 'di chuyển', do đó thay đổi đối với bất kỳ đồng phục nào sẽ chỉ ảnh hưởng đến các cuộc gọi được thực hiện sau khi thay đổi. Tôi đặt một đoạn mã mẫu nhỏ vào câu trả lời của tôi để giúp bạn hiểu. – Tim

+0

@Legion được cập nhật với nhận xét mới và giải thích – Tim

Các vấn đề liên quan