想要在从blender导入的实体3d对象上绘制线框网格

时间:2014-02-05 06:47:26

标签: c++ opengl

所以我有这个生物,我希望有三种不同的模式,一个实体,一个线框和两者。使用glOffset的所有示例似乎都不适用于我。

这是我的展示:

// This function is called to display the scene.
void display()
{   
    //Background color
    glClearColor(1, 1, 1, 0);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 
    glEnable(GL_DEPTH_TEST);

    // Matrix setup
    glMatrixMode(GL_PROJECTION);
    glViewport(0, 0, width, height);
    glLoadIdentity();
    gluPerspective(40, (float)width / (float)height, 0.1, 1000);

    // Matrix setup
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glTranslatef(0, 0, -3);


    //draw object
    glBegin(GL_TRIANGLES);
        for (int i = 0; i<mesh->nfaces.size(); i += 1)
            for (int j = 0; j<3; j += 1){
                glNormal3f(mesh->normal[mesh->nfaces[i][j]][0],
                mesh->normal[mesh->nfaces[i][j]][1],
                mesh->normal[mesh->nfaces[i][j]][2]);

                glVertex3f(mesh->vertex[mesh->faces[i][j]][0],
                mesh->vertex[mesh->faces[i][j]][1],
                mesh->vertex[mesh->faces[i][j]][2]);
            }
    glEnd();



    glutSwapBuffers();
}

我试图实现恶作剧的键盘代码:

void keyboard(unsigned char key, int x, int y)
{
    float colorBronzeDiff[4] = { 0.8, 0.6, 0.0, 1.0 };
    switch (key)
    {
        case(27) :
            exit(0);
            break;
        case('s') :
        {
                      int myFlagCtr = getFlagCtr();
                      cout << "Pressed Before: " << getFlagCtr() << endl;
                      if (myFlagCtr == 0) {
                          glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);


                          setFlagCtr(1);
                      }
                      else if (myFlagCtr == 1) {
                          glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);

                            setFlagCtr(2);
                      } 
                      else if (myFlagCtr == 2) {
                          glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
                          glEnable(GL_POLYGON_OFFSET_FILL);
                          glPolygonOffset(1.0f, 1.0f);
                          glColor3f(0.0f, 1.0f, 0.0f);
                          // draw
                            glDisable(GL_POLYGON_OFFSET_FILL);


                            glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
                            //glEnable( GL_POLYGON_OFFSET_LINE );
                            //glPolygonOffset( -2.0f, -2.0f );
                            glColor3f(1.0f, 0.0f, 0.0f);
                            glLineWidth(1.0f);
                            // draw
                            //glDisable( GL_POLYGON_OFFSET_LINE );
                            setFlagCtr(0);

                          cout << "Pressed Before: " << getFlagCtr() << endl;
                      }
                      break;
        }
    }
}

这是主要的:

void main(int argc, char **argv)
{

    // GLUT initialization.
    glutInit(&argc, argv);  
    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
    glutInitWindowSize(width, height);
    glutCreateWindow("CodeBase");

    // Register call backs.
    initialize();
    glutDisplayFunc(display);
    glutReshapeFunc(reshapeMainWindow);
    glutMotionFunc(mouse_motion);
    glutIdleFunc(idle);
    glutKeyboardFunc(keyboard);
    glutMouseFunc(mouse_button);

    // Enter GLUT loop.
    glutMainLoop();

    delete mesh;
}

我认为我应该做的是将图像绘制两次然后抵消它,但对于我的生活,我似乎无法让它工作。我无法通过将其直接显示并尝试绘制对象两次来默认显示此类模式。

编辑:回复最新答案。

glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glEnable(GL_POLYGON_OFFSET_FILL);
glPolygonOffset(1.0f, 1.0f);
glColor3f(0.0f, 1.0f, 0.0f);
// draw
//draw object
glBegin(GL_TRIANGLES);
    for (int i = 0; i<mesh->nfaces.size(); i += 1)
        for (int j = 0; j<3; j += 1){
            glNormal3f(mesh->normal[mesh->nfaces[i][j]][0],
            mesh->normal[mesh->nfaces[i][j]][1],
            mesh->normal[mesh->nfaces[i][j]][2]);

            glVertex3f(mesh->vertex[mesh->faces[i][j]][0],
            mesh->vertex[mesh->faces[i][j]][1],
            mesh->vertex[mesh->faces[i][j]][2]);
        }
glEnd();
glDisable(GL_POLYGON_OFFSET_FILL);

glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
glColor3f(1.0f, 0.0f, 0.0f);
glLineWidth(1.0f);
// draw
//draw object
glBegin(GL_TRIANGLES);
for (int i = 0; i<mesh->nfaces.size(); i += 1)
for (int j = 0; j<3; j += 1){
    glNormal3f(mesh->normal[mesh->nfaces[i][j]][0],
        mesh->normal[mesh->nfaces[i][j]][1],
        mesh->normal[mesh->nfaces[i][j]][2]);

    glVertex3f(mesh->vertex[mesh->faces[i][j]][0],
        mesh->vertex[mesh->faces[i][j]][1],
        mesh->vertex[mesh->faces[i][j]][2]);
}
glEnd();

1 个答案:

答案 0 :(得分:1)

如果希望图像在线框和实体模式下渲染,则必须实际执行几何渲染函数(例如:glBegin() ... glEnd())两次。

在键盘回调的第三个设置中,您可以调用

glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);

但是你不会在这两个调用之间绘制任何几何。 GL是状态机,因此只有对给定状态的最后一次更改(在这种情况下为多边形绘制模式)才会影响渲染。

你的setFlagCtr调用应该在键盘回调函数中,但所有其他的东西应该在draw函数中,对于wire + solid模式,你必须确保你在调用这个部分至少两次:

glBegin(GL_TRIANGLES);
...
glEnd();

长话短说,除了显示功能之外,不要将GL状态或渲染管理调用放在任何地方。