Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
142 views
in Technique[技术] by (71.8m points)

c++ - Anyone know why this particular object is being rendered in front of another object, despite its z-coordinates?

I'm recreating a 2D scene in 3D with OpenGL. My goal is to recreate an image of a desk with a monitor, tower, keyboard, and mouse. So far I have rendered the monitor and screen for the monitor. The z-coordinates for the monitor (the gray box) originally were greater than the z-coordinates for the flat white screen since the screen is supposed to be in front of it. However, when it renders, the exact opposite of what you would expect occurs. The screen renders behind the rectangular cube. I can tell when I apply a 180 degree rotation to my rotation matrix. So when I adjust the z-coordinates to make the screen's greater than the monitor's, then it appears in front. But as the z-coordinate increases, objects should be going further into the distance, so that's really odd.

Here's a screenshot of when the screen's z-coordinates are greater than the monitor's:

monitor with screen

Here are the same two objects rotated 45 degrees:

monitor with screen rotated 45 degrees

Of course, that's how it's supposed to look, but only when the screen's coordinates are less than the monitor's. Here's some relevant code to help you understand what I'm talking about. I left some code out that I didn't think would be relevant. Please tell me if you need me to provide more code.

void uCreateScreenMesh(GLMesh& mesh) {
    GLfloat vertices[] = {
        -0.25f, 0.95f, 0.81f,       1.0f, 1.0f, 1.0f, 1.0f, //0
        -0.25f, 0.65f, 0.81f,       1.0f, 1.0f, 1.0f, 1.0f, //1
         0.25f, 0.65f, 0.81f,       1.0f, 1.0f, 1.0f, 1.0f, //2
         0.25f, 0.95f, 0.81f,       1.0f, 1.0f, 1.0f, 1.0f  //3
    };

    GLushort indices[] = {
        0, 1, 2,
        0, 3, 2
    };

    const GLuint floatsPerVertex = 3;
    const GLuint floatsPerColor = 4;
    const GLint stride = sizeof(float) * (floatsPerVertex + floatsPerColor);
    mesh.nIndices = sizeof(indices) / sizeof(indices[0]);

    glGenVertexArrays(1, &mesh.vao);
    glBindVertexArray(mesh.vao);

    glGenBuffers(2, mesh.vbo);
    glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.vbo[1]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    //create vertex attribute pointers
    glVertexAttribPointer(0, floatsPerVertex, GL_FLOAT, GL_FALSE, stride, 0);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, floatsPerColor, GL_FLOAT, GL_FALSE, stride, (char*)(sizeof(float) * floatsPerVertex));
    glEnableVertexAttribArray(1);
}

void uCreateMonitorMesh(GLMesh& mesh)
{
    GLfloat vertices[] = {
        //monitor (rectangle)
        -0.3f, 1.0f, 0.75f,         0.5f, 0.5f, 0.5f, 1.0f, //0
        -0.3f, 1.0f, 0.8f,          0.5f, 0.5f, 0.5f, 1.0f, //1
        
        -0.3f, 0.6f, 0.75f,         0.5f, 0.5f, 0.5f, 1.0f, //2
        -0.3f, 0.6f, 0.8f,          0.5f, 0.5f, 0.5f, 1.0f, //3
 
         0.3f, 0.6f, 0.75f,          0.5f, 0.5f, 0.5f, 1.0f, //4
         0.3f, 0.6f, 0.8f,           0.5f, 0.5f, 0.5f, 1.0f, //5

         0.3f, 1.0f, 0.75f,          0.5f, 0.5f, 0.5f, 1.0f, //6
         0.3f, 1.0f, 0.8f,           0.5f, 0.5f, 0.5f, 1.0f  //7



        
    };

    GLushort indices[] = {
        //monitor front
        0, 2, 4,
        0, 6, 4,

        //top
        0, 1, 7,
        0, 6, 7,

        //left side
        0, 3, 1,
        0, 2, 1,

        //bottom side
        2, 3, 5,
        2, 5, 4,

        //right side
        4, 5, 6,
        4, 7, 6,

        //monitor back
        1, 3, 5,
        1, 7, 5
    };

    const GLuint floatsPerVertex = 3;
    const GLuint floatsPerColor = 4;
    const GLint stride = sizeof(float) * (floatsPerVertex + floatsPerColor);
    mesh.nIndices = sizeof(indices) / sizeof(indices[0]);

    glGenVertexArrays(1, &mesh.vao);
    glBindVertexArray(mesh.vao);

    glGenBuffers(2, mesh.vbo);
    glBindBuffer(GL_ARRAY_BUFFER, mesh.vbo[0]);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mesh.vbo[1]);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);

    //create vertex attribute pointers
    glVertexAttribPointer(0, floatsPerVertex, GL_FLOAT, GL_FALSE, stride, 0);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, floatsPerColor, GL_FLOAT, GL_FALSE, stride, (char*)(sizeof(float) * floatsPerVertex));
    glEnableVertexAttribArray(1);
}

void uRender()
{
    //enable z-depth
    glEnable(GL_DEPTH_TEST);

    //clear frame and z buffers
    glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    glm::mat4 scale = glm::scale(glm::vec3(1.2f, 1.2f, 1.2f));
    glm::mat4 rotation = glm::rotate(glm::radians(0.f), glm::vec3(0.0f, 1.0f, 0.0f));
    glm::mat4 translation = glm::translate(glm::vec3(0.0f, 0.0f, 0.0f));

    glm::mat4 model = translation * rotation * scale;

    glm::mat4 view = glm::translate(glm::vec3(0.0f, 0.0f, -3.5f));

    glm::mat4 projection = glm::perspective(45.0f, (GLfloat)WINDOW_WIDTH / (GLfloat)WINDOW_HEIGHT, 0.1f, 100.0f);

    glUseProgram(programId);

    GLint modelLoc = glGetUniformLocation(programId, "model");
    GLint viewLoc = glGetUniformLocation(programId, "view");
    GLint projLoc = glGetUniformLocation(programId, "projection");

    glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
    glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
    glUniformMatrix4fv(projLoc, 1, GL_FALSE, glm::value_ptr(projection));

    glBindVertexArray(screenMesh.vao);
    glDrawElements(GL_TRIANGLES, screenMesh.nIndices, GL_UNSIGNED_SHORT, NULL);

    glBindVertexArray(monitorMesh.vao);
    glDrawElements(GL_TRIANGLES, monitorMesh.nIndices, GL_UNSIGNED_SHORT, NULL);
    
    

    glBindVertexArray(0);
    glfwSwapBuffers(window);
}

I tried changing the order in which the vertex array object is binded, but as I expected that didn't change anything.

All help appreciated, thank you.

question from:https://stackoverflow.com/questions/65866445/anyone-know-why-this-particular-object-is-being-rendered-in-front-of-another-obj

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)
Waitting for answers

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...