按照RedBook中的代码在OpenGL中绘制二十面体时缺少面孔 [英] Faces missing when drawing icosahedron in OpenGL following code in redBook

查看:92
本文介绍了按照RedBook中的代码在OpenGL中绘制二十面体时缺少面孔的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在此流行的OpenGl教程中绘制二十面体红皮书.

I am attempting to draw an icosahedron following this popular OpenGl tutorial in the redBook.

我正在使用GLUT处理窗口.

I am using GLUT to handle windowing.

这是我完整的代码.它主要是本教程中的代码以及使用GLUT进行的一些文书工作

Here is my complete code. It is mostly the code from the tutorial plus some clerical work using GLUT

#include <stdio.h>
#include <GL/glut.h>
#define X .525731112119133606
#define Z .850650808352039932

void mouseEventHandler(int button, int state, int x, int y){
}

void display() {
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    static GLfloat vdata[12][3] = {
        {-X,0.0,Z}, {X,0.0,Z}, {-X,0.0,-Z}, {X,0.0,-Z},
        {0.0,Z,X}, {0.0,Z,-X}, {0.0,-Z,X}, {0.0,-Z,-X},
        {Z,X,0.0}, {-Z,X,0.0}, {Z,-X,0.0}, {-Z,-X,0.0},
    };

    static GLuint tindices[20][3] = { 
        {0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},    
        {8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},    
        {7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6}, 
        {6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11} };

    int i;

    glBegin(GL_TRIANGLES);
    for (i = 0; i < 20; i++){
        glNormal3fv(&vdata[tindices[i][0]][0]);
        glVertex3fv(&vdata[tindices[i][0]][0]);
        glNormal3fv(&vdata[tindices[i][1]][0]);
        glVertex3fv(&vdata[tindices[i][1]][0]);
        glNormal3fv(&vdata[tindices[i][2]][0]);
        glVertex3fv(&vdata[tindices[i][2]][0]);
    }
    glEnd();
    glFlush ( );
}

void windowSetup(){
    glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);

    glutInitWindowPosition(80, 80);
    glutInitWindowSize(1000,1000);

    glutCreateWindow("OpenGL Ico");

    glClear(GL_COLOR_BUFFER_BIT);
    glMatrixMode( GL_MODELVIEW);
    glLoadIdentity();           
    gluOrtho2D( -2.0, 2.0, -2.0, 2.0 );
}

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

    glutInit(&argc, argv);
    windowSetup();

    glutDisplayFunc(display);
    glutMouseFunc(&mouseEventHandler);
    glutMainLoop();
}

这是我的输出: 这与预期的输出有很大不同:

This is my output: This is very different from the expected output:

有人知道为什么这些差异如此大吗?

Does someone know why these differ so much?

差异似乎是:

  • 我的二十面体缺少面孔

  • My icosahedron is missing faces

我的二十面体正以不同的角度观看

My icosahedron is being viewed from a different angle

我的二十面体的照明方式不同

My icosahedron is lit differently

第一个是最紧迫的.我已经注意到,当我将glMatrixMode( GL_MODELVIEW);更改为glMatrixMode( GL_PROJECTION);时,没有出现的面孔会出现,而当前出现的面孔会消失.有人知道为什么会这样吗?

The first one is the most pressing. I have noticed when I change glMatrixMode( GL_MODELVIEW); to glMatrixMode( GL_PROJECTION); the faces that aren't showing up appear and those that are currenty appearing disappear. Does anybody know why this could be?

推荐答案

  1. 缺少面孔

很可能您只是索引顺序错误.在这种情况下,将它们反向可以解决问题.要检查这一点,您可以尝试:

most likely you just have wrong order of indices. In such case Reversing them will solve the issue. To check this you can try:

glDisable(GL_CULL_FACE);

如果问题消失,我是对的.如果不是这样的话,那就不一样了(比如太接近Z_NEAR的镜头切割,但是看起来会有些不同).

if problem disappears I am right. If not it is different thing (like too close to camera cutting by Z_NEAR but that would look a bit different).

要确定正确的面孔,您可以使用基于iglColor作为示例

To identify the correct face you can use glColor based on i for exaple

if (i==5) glColor3f(1.0,0.0,0.0); else glColor3f(1.0,1.0,1.0);

在这种情况下,红脸将是第六个{8,3,10}

the red face would be the 6th in this case {8,3,10}

照明

您将顶点坐标用作法线,因此不要期望 FLAT 阴影.另外,我看不到您在此处设置任何灯光(但可以将其隐藏在我不使用的 GLUT 中).为了解决这个问题,每个三角形仅使用一个法线即可.因此,平均得到的3个法线,并从中得出一个单位向量并使用该向量(在每个三角形的第一个glVertex调用之前).

You are using vertex coordinates as normals so do not expect FLAT shading. Also I do not see you are setting any lights here (but that can be hidden in GLUT somewhere I do not use it). To remedy this use just single normal per triangle. so average the 3 normals you got and make an unit vector from that and use that (before first glVertex call of each triangle).

方向

只需将GL_MODELVIEW旋转到所需方向即可.标准透视图GL_PROJECTION具有z轴作为查看方向,并且x,y轴与屏幕匹配(GL_MODELVIEW为单位)

just rotate your GL_MODELVIEW to desired orientation. Standard perspective GL_PROJECTION has z axis as viewing direction and x,y axises matches the screen (while GL_MODELVIEW is unit)

[Edit1]我尝试了您的代码

所以问题是,您得到了相反的索引顺序,然后在OpenGL中(至少在我的环境中)使用了默认的多边形缠绕,并且这里的法线错误固定了代码:

So the problem is you got reverse order of indices then default polygon winding in OpenGL (at least in my environment) and wrong normals here fixed code:

glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
const GLfloat vdata[12][3] =
    {
    {-X,0.0,Z}, {X,0.0,Z}, {-X,0.0,-Z}, {X,0.0,-Z},
    {0.0,Z,X}, {0.0,Z,-X}, {0.0,-Z,X}, {0.0,-Z,-X},
    {Z,X,0.0}, {-Z,X,0.0}, {Z,-X,0.0}, {-Z,-X,0.0},
    };

const GLuint tindices[20][3] =
    {
    {0,4,1}, {0,9,4}, {9,5,4}, {4,5,8}, {4,8,1},
    {8,10,1}, {8,3,10}, {5,3,8}, {5,2,3}, {2,7,3},
    {7,10,3}, {7,6,10}, {7,11,6}, {11,0,6}, {0,1,6},
    {6,1,10}, {9,0,11}, {9,11,2}, {9,2,5}, {7,2,11}
    };

int i;
GLfloat nx,ny,nz;

glEnable(GL_CULL_FACE);
glFrontFace(GL_CW);
glBegin(GL_TRIANGLES);
for (i = 0; i < 20; i++)
    {
    nx =vdata[tindices[i][0]][0];
    ny =vdata[tindices[i][0]][1];
    nz =vdata[tindices[i][0]][2];
    nx+=vdata[tindices[i][1]][0];
    ny+=vdata[tindices[i][1]][1];
    nz+=vdata[tindices[i][1]][2];
    nx+=vdata[tindices[i][2]][0]; nx/=3.0;
    ny+=vdata[tindices[i][2]][1]; ny/=3.0;
    nz+=vdata[tindices[i][2]][2]; nz/=3.0;
    glNormal3f(nx,ny,nz);
    glVertex3fv(vdata[tindices[i][0]]);
    glVertex3fv(vdata[tindices[i][1]]);
    glVertex3fv(vdata[tindices[i][2]]);
    }
glEnd();

预览:

这是屏幕截图,并且我的对象正在旋转,所以不要期望您期望的正确方向.

it is a screenshot and my object is rotating so do not expect correct orientation you expect.

这篇关于按照RedBook中的代码在OpenGL中绘制二十面体时缺少面孔的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆