2013-09-07 41 views
5

Tôi khá mới với opengl và tôi không thực sự hiểu những gì đang xảy ra ở đây. Tôi đang cố gắng sử dụng hai VAO để tạo nhiều đối tượng và đang sử dụng ma trận tùy chỉnh để xoay/dịch chúng. Hình ảnh là tốt khi tôi tải lên một, nhưng khi tôi tải lên hai họ đều nhấp nháy. Init của tôi là cái này, nơi tôi có một mảng khác nhau cho mỗi bộ đệm, vị trí đỉnh, các chỉ số đỉnh và các màu đỉnh.opengl nhấp nháy trong khi hiển thị nhiều đối tượng

void init() 
{ 
readFile(); 
//glEnable(GL_DEPTH); 
glEnable(GL_DEPTH_TEST); 
//make background yerpul in colour 
glClearColor(0.235, 0.194, 0.314, 1.0); 


    // Load shaders and use the resulting shader program 
    program = InitShader("aVertexShader61.glsl", "aFragShader61.glsl"); 
    glUseProgram(program); 

    // Create a vertex array object 
    glGenVertexArrays(1, &vao); 
    glBindVertexArray(vao); 

    // Create and initialize two buffer objects 
    glGenBuffers(2, buffers); 

    //one buffer for the vertexPositions and colours 
    glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); 
    glBufferData(GL_ARRAY_BUFFER, numVertexPositionBytes + numVertexColourBytes,NULL, GL_STATIC_DRAW); 
    glBufferSubData(GL_ARRAY_BUFFER, 0, numVertexPositionBytes, vertexPositions); 
    glBufferSubData(GL_ARRAY_BUFFER, numVertexPositionBytes, numVertexColourBytes, vertexColours); 

    //one buffer for the indices 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, numVertexIndexBytes,vertexIndicies, GL_STATIC_DRAW); 

    // set up vertex arrays 
    GLuint vPosition = glGetAttribLocation(program, "vPosition"); 
    glEnableVertexAttribArray(vPosition); 
    glVertexAttribPointer(vPosition, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); 

    GLuint vColor = glGetAttribLocation(program, "vColor"); 
    glEnableVertexAttribArray(vColor); 
    glVertexAttribPointer(vColor, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(numVertexPositionBytes)); 

    // Second object 

    glGenVertexArrays(1, &vao2); 
    glBindVertexArray(vao2); 

    glGenBuffers(2, buffers2); 

    //one buffer for the vertexPositions and colours 
    glBindBuffer(GL_ARRAY_BUFFER, buffers2[0]); 
    glBufferData(GL_ARRAY_BUFFER, numVertexPositionBytes + numVertexColourBytes,NULL, GL_STATIC_DRAW); 
    glBufferSubData(GL_ARRAY_BUFFER, 0, numVertexPositionBytes, vertexPositions2); 
    glBufferSubData(GL_ARRAY_BUFFER, numVertexPositionBytes, numVertexColourBytes, vertexColours2); 

    //one buffer for the indices 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers2[1]); 
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, numVertexIndexBytes,vertexIndicies2, GL_STATIC_DRAW); 

    // set up vertex arrays 
    GLuint vPosition2 = glGetAttribLocation(program, "vPosition"); 
    glEnableVertexAttribArray(vPosition2); 
    glVertexAttribPointer(vPosition2, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(0)); 

    GLuint vColor2 = glGetAttribLocation(program, "vColor"); 
    glEnableVertexAttribArray(vColor2); 
    glVertexAttribPointer(vColor2, 4, GL_FLOAT, GL_FALSE, 0, BUFFER_OFFSET(numVertexPositionBytes)); 


    glBindVertexArray(0); 
} 

Đây là màn hình của tôi được gọi với glutPostRedisplay(); trong chức năng nhàn rỗi của tôi, không có cuộc gọi nào khác đến bất cứ thứ gì được thực hiện từ chế độ chờ. mStack là đối tượng ngăn xếp ma trận được tạo từ một tệp bên ngoài

void 
    display(void) 
{ 

    //clear for first object, generate matrix and apply to object 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    mStack.loadIdentity(); 
    mStack.translatef(0,yDisplace,0); 
    mStack.rotatef(Theta[Yaxis], 0.0,1.0,0.0); 
    for (unsigned char i=0; i<NumVertices; i++){ 
     mStack.transformf(&vertexPositionsInit[i*4],&vertexPositions[i*4]); 

    } 

    //Apply to second object 
    for (unsigned char i=0; i<NumVertices; i++){ 
     mStack.transformf(&vertexPositionsInit2[i*4],&vertexPositions2[i*4]); 

    } 


    //Draw first object 
    glBindVertexArray(vao); 
    glBindBuffer(GL_ARRAY_BUFFER, buffers[0]); 
    glBufferSubData(GL_ARRAY_BUFFER, 0, numVertexPositionBytes, vertexPositions); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]); 
    //Indexing into vertices we need to use glDrawElements 
    glDrawElements(GL_TRIANGLES, NumIndicies, GL_UNSIGNED_BYTE, 0); 
    glutSwapBuffers(); 


    //Clear and draw second object 
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glutSwapBuffers(); 
    glBindVertexArray(vao2); 
    glBindBuffer(GL_ARRAY_BUFFER, buffers2[0]); 
    glBufferSubData(GL_ARRAY_BUFFER, 0, numVertexPositionBytes, vertexPositions2); 
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers2[1]); 
    //Indexing into vertices we need to use glDrawElements 
    glDrawElements(GL_TRIANGLES, NumIndicies, GL_UNSIGNED_BYTE, 0); 
    glutSwapBuffers(); 


} 

Tôi đang sử dụng các trình đổ bóng đỉnh và mảnh đơn giản. Các vertex shader,

in vec4 vPosition; 
in vec4 vColor; 
out vec4 color; 

void main() 
{ 
    gl_Position = vPosition; 
    color = vColor; 
} 

Và fragment shader

in vec4 color; 
out vec4 fColor; 

void main() 
{ 
    fColor = color; 
} 

Bất kỳ trợ giúp sẽ được đánh giá cao, và tôi có thể gửi các tập tin Matrix nếu cần thiết. Cảm ơn

+0

Lưu ý phụ: các trình đổ bóng bạn đang sử dụng được gọi là trình đổ bóng "chuyển tiếp", có nghĩa là nếu bạn không sử dụng trình đổ bóng, bạn sẽ nhận được cùng một đầu ra. Hầu hết mã ma trận đó có thể đi vào các trình đổ bóng, mặc dù tất nhiên bạn sửa một thứ tại một thời điểm. :) –

+0

đây có phải là vấn đề do tính toán ma trận không? Tôi nghĩ rằng nó phải là một vấn đề đệm đó là lý do tại sao tôi không bao gồm mã ma trận nhưng tôi thực sự không có ý tưởng. – user2755996

+0

Mã ma trận sẽ xác định vị trí đối tượng của bạn "là". Nếu bạn nhìn thấy một vật thể nhưng nó nhấp nháy hoặc để lại một dấu vết, đó không phải là vấn đề ma trận. –

Trả lời

5

Đừng gọi glutSwapBuffers() hoặc glClear() ở giữa các đối tượng. Trao đổi bộ đệm là một cách để nói với GLUT "Được rồi, tôi đã làm xong với khung này, hãy bắt đầu với cái tiếp theo."

Thông thường bạn sẽ muốn tách mã thiết lập và hoàn thành mỗi khung (như các cuộc gọi đến glClear()glutSwapBuffers()) từ mã hiển thị từng đối tượng, vì OpenGL về cơ bản là một hộp khổng lồ các biến toàn cục và khó có thể viết mã OpenGL tốt mà không phá vỡ các phương pháp của bạn thành từng phần nhỏ.

+0

Cảm ơn bạn đã trả lời, tôi nhận xét bộ đệm rõ ràng và trao đổi và bây giờ đối tượng thứ hai để lại một đường viền của khung hình và nền mờ: – user2755996

+0

Bạn có nhận xét tất cả chúng, hoặc chỉ là những cái giữa các đối tượng? Bạn vẫn cần một glClear() ở đầu và một glutSwapBuffers() ở cuối. Có vẻ như bạn đã nhận được mã làm việc cho một đối tượng và sao chép tất cả mã đó cho lần thứ hai, nhưng một số cuộc gọi này là một lần cho mỗi khung hình và một số khác là một lần cho mỗi đối tượng. –

+0

Điều đó đã làm điều đó :), trước đây tôi đã có một bộ đệm trao đổi ở cuối mỗi đối tượng thay vì kết thúc phần vẽ cho cả hai. Cảm ơn rất nhiều Steve – user2755996

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