绘制球体并计算曲面法线

时间:2013-12-02 20:25:53

标签: opengl-es-2.0

我正在尝试绘制球体并计算其表面法线。我一直盯着这几个小时,但我无处可去。这是一个混乱的截图:

enter image description here

- (id) init
{
    if (self = [super init]) {

        glGenVertexArraysOES(1, &_vertexArray);
        glBindVertexArrayOES(_vertexArray);

        glGenBuffers(1, &_vertexBuffer);
        glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);

        GLfloat rad_th, rad_ph;
        GLint th, ph;
        GLint i = 0;

        GLKMatrix3 this_triangle;
        GLKVector3 column0, column1, column2, this_normal;

        for (ph=-90; ph<=90; ph++) {
            for (th=0; th<=360; th+=10) {

                if (i<3) printf("i: %d th: %f  ph: %f\n", i, (float)th, (float)ph);
                rad_th = GLKMathDegreesToRadians( (float) th );
                rad_ph = GLKMathDegreesToRadians( (float) ph);

                _vertices[i][0][0] = sinf(rad_th)*cosf(rad_ph);
                _vertices[i][0][1] = sinf(rad_ph);
                _vertices[i][0][2] = cos(rad_th)*cos(rad_ph);

                rad_th = GLKMathDegreesToRadians( (float) (th) );
                rad_ph = GLKMathDegreesToRadians( (float) (ph+1) );

                _vertices[i+1][0][0] = sinf(rad_th)*cosf(rad_ph);    
                _vertices[i+1][0][1] = sinf(rad_ph);     
                _vertices[i+1][0][2] = cos(rad_th)*cos(rad_ph);

                i+=2;
            }
        }

        // calclate and store the surface normal for every triangle
        i=2;
        for (ph=-90; ph<=90; ph++) {
            for (th=2; th<=360; th++) {
                // note that the first two vertices are irrelevant since it isn't until the third vertex that a triangle is defined.

                column0 = GLKVector3Make(_vertices[i-2][0][0], _vertices[i-2][0][1], _vertices[i-2][0][2]);
                column1 = GLKVector3Make(_vertices[i-1][0][0], _vertices[i-1][0][1], _vertices[i-1][0][2]);
                column2 = GLKVector3Make(_vertices[i-0][0][0], _vertices[i-0][0][1], _vertices[i-0][0][2]);
                this_triangle = GLKMatrix3MakeWithColumns(column0, column1, column2);
                this_normal = [self calculateTriangleSurfaceNormal : this_triangle];
                _vertices[i][1][0] = this_normal.x;
                _vertices[i][1][1] = this_normal.y;
                _vertices[i][1][2] = this_normal.z;                    

                i++;
            }
    i+=2;
        }

        glBufferData(GL_ARRAY_BUFFER, sizeof(_vertices), _vertices, GL_STATIC_DRAW);
        glEnableVertexAttribArray(GLKVertexAttribPosition);
        glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*6, NULL);
        glEnableVertexAttribArray(GLKVertexAttribNormal);
        glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, sizeof(GLfloat)*6, (GLubyte*)(sizeof(GLfloat)*3));

        glBindVertexArrayOES(0);

    }

    return self;

}
  • (void)渲染; { glDrawArrays(GL_TRIANGLE_STRIP,0,65522); }

这是我的表面法线计算。我已经在其他地方使用过这个,所以我认为如果给出正确的顶点,它的确有效。

- (GLKVector3) calculateTriangleSurfaceNormal : (GLKMatrix3) triangle_vertices
{
    GLKVector3 surfaceNormal;

    GLKVector3 col0 = GLKMatrix3GetColumn(triangle_vertices, 0);
    GLKVector3 col1 = GLKMatrix3GetColumn(triangle_vertices, 1);
    GLKVector3 col2 = GLKMatrix3GetColumn(triangle_vertices, 2);

    GLKVector3 vec1 = GLKVector3Subtract(col1, col0);
    GLKVector3 vec2 = GLKVector3Subtract(col2, col0);

    surfaceNormal.x = vec1.y * vec2.z - vec2.y * vec1.z;
    surfaceNormal.y = vec1.z * vec2.x - vec2.z * vec1.x;
    surfaceNormal.z = vec1.x * vec2.y - vec2.x * vec1.y;

    return GLKVector3Normalize(surfaceNormal);

}

在我的.h文件中,我像这样定义_vertices数组(如果你愿意,那就笑......):

// 360 + 2 = 362 vertices per triangle strip
// 90 strips per hemisphere (one hemisphere has 91)
// 2 hemispheres
// 362 * 90.5 * 2 = 65522
GLfloat _vertices[65522][2][3]; //2 sets (vertex, normal) and 3 vertices in each set

1 个答案:

答案 0 :(得分:0)

看起来您正在计算三角形条带中三角形的法线,但是将这些法线分配给由多个三角形共享的顶点。如果您只使用三角形而不是三角形条带,并且从三角形正常的每个三角形给出所有三个顶点,则每个三角形将具有适当的法线。这个值实际上只对三角形的中心是正确的。你最好使用顶点法线,正如克里斯蒂安提到的那样,在这种情况下等于顶点。这些可以在三角形中插值。