问题
I am attempting to draw an icosahedron following this popular OpenGl tutorial in the redBook.
I am using GLUT to handle windowing.
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?
The differences seem to be:
My icosahedron is missing faces
My icosahedron is being viewed from a different angle
My icosahedron is lit differently
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:
missing faces
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);
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).To identify the correct face you can use
glColor
based oni
for exapleif (i==5) glColor3f(1.0,0.0,0.0); else glColor3f(1.0,1.0,1.0);
the red face would be the 6th in this case
{8,3,10}
lighting
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).orientation
just rotate your
GL_MODELVIEW
to desired orientation. Standard perspectiveGL_PROJECTION
hasz
axis as viewing direction andx,y
axises matches the screen (whileGL_MODELVIEW
is unit)
[Edit1] I tried your code
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();
And preview:
it is a screenshot and my object is rotating so do not expect correct orientation you expect.
来源:https://stackoverflow.com/questions/43107006/faces-missing-when-drawing-icosahedron-in-opengl-following-code-in-redbook