一筆書

球を効率良く一筆stripでかけないだろうか?どう書くんだろう?なんかそれっぽい奴書くときはついつい怠けて

#define APPEND_VTX(vertex, x,y,z) \
    {*vertex++ = (x); *vertex++ = (y); *vertex++ = (z);}
////  -- make sphere points  球の頂点配列作る
  { float y, r;
    float *p = vertex;

  // 下から始める
    APPEND_VTX(p, 0, -1, 0);
    for (y = -1.0f+0.1f; y< 1.0f-0.1f; y += 0.1f)
       for (r = 0; r< 2.0f*M_PI; r+= 2.0f*M_PI/DIV) {
          APPEND_VTX(p, sqrtf(1.0-y*y) *cos(r), y, sqrtf(1.0-y*y) *sin(r));
       }
    APPEND_VTX(p, 0,  1.0f, 0);
  // できあがり

    size = (int)(p - vertex);
  }
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(3, GL_FLOAT, 0, vertex);

     :

     :
    // Draw  
    glBegin(GL_TRIANGLE_FAN); {
        int i;
        glColor3f(0,1.0, 0);
        glArrayElement(0);
        for (i = 1; i< DIV+1; i++) {
          glArrayElement(i);
        }
        glArrayElement(1);
    } glEnd();

    glColor3f(1.0, 1.0, 1.0);
    for (y = -1.0f+0.1f; y<= 0.9f; y+=0.1f) {
        int i;
        glBegin(GL_TRIANGLE_STRIP);
          for (i = base; i< base+DIV; i++) {
            glArrayElement(i);
            glArrayElement(i+DIV);
          }
          glArrayElement(base);
          glArrayElement(base+DIV);
        glEnd();
        base += DIV;
    }

上蓋と下蓋を描画した後一行ずつ帯を書いてる。

ストリップを自動で計算するってのもおもしろそうなのだけど、今の私には手に余るので。で、、お世話になりっぱなしのgluを参照してみる。

/mesa-7.0.1/src/glu/sgi/libutil/quad.c

void GLAPIENTRY
gluSphere(GLUquadric *qobj, GLdouble radius, GLint slices, GLint stacks)
{
    :
    :
      case GLU_LINE:
      case GLU_SILHOUETTE:
        for (j = 1; j < stacks; j++) {
            sintemp1 = sinCache1b[j];
            costemp1 = cosCache1b[j];
            switch(qobj->normals) {
              case GLU_FLAT:
              case GLU_SMOOTH:
                sintemp2 = sinCache2b[j];
                costemp2 = cosCache2b[j];
                break;
              default:
                break;
            }

            glBegin(GL_LINE_STRIP);
            for (i = 0; i <= slices; i++) {
                switch(qobj->normals) {
                  case GLU_FLAT:
                    glNormal3f(sinCache3a[i] * sintemp2,
                            cosCache3a[i] * sintemp2,
                            costemp2);
                    break;
                  case GLU_SMOOTH:
                    glNormal3f(sinCache2a[i] * sintemp2,
                            cosCache2a[i] * sintemp2,
                            costemp2);
                    break;
                  case GLU_NONE:
                  default:
                    break;
                }
                if (qobj->textureCoords) {
                    glTexCoord2f(1 - (float) i / slices,
                            1 - (float) j / stacks);
                }
                glVertex3f(sintemp1 * sinCache1a[i],
                        sintemp1 * cosCache1a[i], costemp1);
            }
            glEnd();
        }
        for (i = 0; i < slices; i++) {
            sintemp1 = sinCache1a[i];
            costemp1 = cosCache1a[i];
            switch(qobj->normals) {
              case GLU_FLAT:
              case GLU_SMOOTH:
                sintemp2 = sinCache2a[i];
                costemp2 = cosCache2a[i];
                break;
              default:
                break;
            }

            glBegin(GL_LINE_STRIP);
            for (j = 0; j <= stacks; j++) {
                switch(qobj->normals) {
                  case GLU_FLAT:
                    glNormal3f(sintemp2 * sinCache3b[j],
                            costemp2 * sinCache3b[j],
                            cosCache3b[j]);
                    break;
                  case GLU_SMOOTH:
                    glNormal3f(sintemp2 * sinCache2b[j],
                            costemp2 * sinCache2b[j],
                            cosCache2b[j]);
                    break;
                  case GLU_NONE:
                  default:
                    break;
                }

                if (qobj->textureCoords) {
                    glTexCoord2f(1 - (float) i / slices,
                            1 - (float) j / stacks);
                }
                glVertex3f(sintemp1 * sinCache1b[j],
                        costemp1 * sinCache1b[j], cosCache1b[j]);
            }
            glEnd();
        }
        break;
      default:
        break;
    }
}

十分これも手に余ってる気がするけど、どうやら同じように stack数分だけ帯を巻いていってるように見える。後で真面目に読もう。