Отображение двух разных объектов на одном экране - PullRequest
0 голосов
/ 29 марта 2019

Я пытаюсь отобразить сферу и тор на одном экране, но кажется, что "glutInitDisplayMode" заставляет меня отображать только одну.Когда я сохраняю его как glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA |GLUT_DEPTH), отображается тор.

Когда я сохраняю его как glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH), отображается сфера.Что я могу сделать, чтобы отобразить оба?

Код рендеринга ниже:

static void render(void) {

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glMatrixMode(GL_MODELVIEW);
    // clear the drawing buffer.
    glClear(GL_COLOR_BUFFER_BIT);
    // clear the identity matrix.
    glLoadIdentity();
    glTranslatef(0.0, 0.0, -5.0);
    glColor3f(0.0, 0.0, 0.0);
    glRotatef(zRotated, 0.0, 0.0, 1.0);
    // scaling transfomation 
    glScalef(1.0, 1.0, 1.0);
    // built-in (glut library) function , draw you a sphere.
    glutSolidTorus(innerRadius, outerRadius, sides, rings);
    // Flush buffers to screen

    glFlush();

  // glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

   // activate our shader program
    glUseProgram(programId);

   // turn on depth buffering
   glEnable(GL_DEPTH_TEST);

   float aspectRatio = (float)width / (float)height;
   glm::mat4 projection = glm::perspective(glm::radians(45.0f), aspectRatio, 0.1f, 1000.0f);


   // view matrix - orient everything around our preferred view
   glm::mat4 view = glm::lookAt(
      glm::vec3(40,30,30), // eye/camera location
      glm::vec3(0,0,0),    // where to look
      glm::vec3(0,1,0)     // up
   );

   // model matrix: translate, scale, and rotate the model
   glm::vec3 rotationAxis(0,1,0);
   glm::mat4 model = glm::mat4(1.0f);
   model = glm::rotate(model, glm::radians(angle), glm::vec3(0, 1, 0)); // rotate about the y-axis
   model = glm::scale(model, glm::vec3(25.0f, 25.0f, 25.0f));

   // model-view-projection matrix
   glm::mat4 mvp = projection * view * model;
   GLuint mvpMatrixId = glGetUniformLocation(programId, "MVP");
   glUniformMatrix4fv(mvpMatrixId, 1, GL_FALSE, &mvp[0][0]);

   // texture sampler - a reference to the texture we've previously created
   // send the texture id to the texture sampler
   GLuint textureUniformId = glGetUniformLocation(programId, "textureSampler");
   glActiveTexture(GL_TEXTURE0);
   glBindTexture(GL_TEXTURE_2D, textureId);
   glUniform1i(textureUniformId, 0);

   // find the names (ids) of each vertex attribute
   GLint positionAttribId = glGetAttribLocation(programId, "position");
   GLint colourAttribId = glGetAttribLocation(programId, "colour");
   GLint textureCoordsAttribId = glGetAttribLocation(programId, "textureCoords");
   GLint normalAttribId = glGetAttribLocation(programId, "normal");

   // provide the vertex positions to the shaders
   glBindBuffer(GL_ARRAY_BUFFER, positions_vbo);
   glEnableVertexAttribArray(positionAttribId);
   glVertexAttribPointer(positionAttribId, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

   // provide the vertex texture coordinates to the shaders
   glBindBuffer(GL_ARRAY_BUFFER, textureCoords_vbo);
   glEnableVertexAttribArray(textureCoordsAttribId);
   glVertexAttribPointer(textureCoordsAttribId, 2, GL_FLOAT, GL_FALSE, 0, nullptr);

   // provide the vertex normals to the shaders
   glBindBuffer(GL_ARRAY_BUFFER, normals_vbo);
   glEnableVertexAttribArray(normalAttribId);
   glVertexAttribPointer(normalAttribId, 3, GL_FLOAT, GL_FALSE, 0, nullptr);

    // draw the triangles
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBuffer);
    glDrawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_INT, (void*)0);

    // disable the attribute arrays
   glDisableVertexAttribArray(positionAttribId);
   glDisableVertexAttribArray(textureCoordsAttribId);
   glDisableVertexAttribArray(normalAttribId);
   glDisableVertexAttribArray(colourAttribId);

    // make the draw buffer to display buffer (i.e. display what we have drawn)
    glutSwapBuffers(); 
}

1 Ответ

2 голосов
/ 29 марта 2019

glutSolidTorus рисует тор, используя фиксированные атрибуты функции. Для этого необходим профиль совместимости Контекст OpenGL .

glutSolidTorus не совместимо с вашей шейдерной программой. Сделайте недействительной текущую установленную программу до glutSolidTorus:

glUseProgram(0);
glutSolidTorus(innerRadius, outerRadius, sides, rings);

Обратите внимание, OpenGL - это движок состояния. Если программа установлена, она сохраняется до тех пор, пока не будет установлена ​​другая программа или она не станет недействительной, даже за рамками. В вашем случае это не проблема в первом кадре, но она все равно будет установлена ​​в начале второго кадра, когда вызывается glutSolidTorus.

Если вы используете окно с двойным буфером (GLUT_DOUBLE), вам нужно позвонить glutSwapBuffers. glutSwapBuffers меняет местами буферы. Буфер, в котором было нарисовано, показано в окне. Буфер, который был show в окне готов для рисования в следующем кадре.

В одном буферизованном окне вы можете сделать glFlush. Это заставляет OpenGL завершить рисование . Поскольку буфер, к которому выполняется рисование, является тем же самым, который показан в окне, это приводит к тому, что все, что рисует в буфер, немедленно отображается в окне.

Переместить одиночный вызов glFlush из середины функции render до конца, прямо перед glutSwapBuffers:

void render()
{
    // ...

    glUseProgram(0);
    glutSolidTorus(innerRadius, outerRadius, sides, rings);

    // glFlush(); <---- delete

    // ...

    glUseProgram(programId);

    // ...

    glDrawElements(GL_TRIANGLES, numVertices, GL_UNSIGNED_INT, (void*)0);

    // ...

    glFlush();
    glutSwapBuffers(); 
}
...